Hi,

I haven't looked at this in detail, but can you please confirm that the following is correct:

1) The query you run in alt. 2 is not identical to alt 1 - there's an extra AND in the WHERE clause, making it an illegal query. Is this just a copy-paste blurp?

2) The alt. 2 output of "Statement text" isn't the SELECT but rather a CALL SYSCS_UTIL.SYSCS_SET_STATISTICS_TIMING(1). Is this correct? If so are you comparing the timing of a SELECT to a CALL? Or am I missing something?

As Knut said, the optimizer sometimes does make bad decisions...

Cheers,
Thomas

DerbyNovice wrote:

PROBLEM STATEMENT
---------------------------------
ALTERNATIVE 1 uses a PreparedStatement with parameters.
ALTERNATIVE 2 mimics a Statement (and indeed a Statement returns the same performance)

...

ALTERNATIVE 1 >
 >1        ps = conn.prepareStatement("SELECT * From SA.UDEVENTDATA  WHERE
DomainKeyId = ? AND CreationTime <  ? AND Name  > ? ");
< END 1
...

ALTERNATIVE 1 >
 >1            ps.setString(3,(String)s2);
 >1            ps.setString(1,"d46chez0v8cdg-c4m");
 >1            ps.setString(2,"1200269947000");
 >1
< END 1

ALTERNATIVE 2 > >2 String sels = "SELECT * From SA.UDEVENTDATA WHERE AND DomainKeyId = 'd46chez0v8cdg-c4m' AND CreationTime < 1200269947000 AND Name
'"+s2+"'  ";
 >2               ps = conn.prepareStatement(sels);
< END 2
            startStat();
            beginTiming_ = java.lang.System.currentTimeMillis ();
            rs = ps.executeQuery();
            endTiming_ = java.lang.System.currentTimeMillis ();
            elapsed = endTiming_ - beginTiming_;
            System.out.println( "?#?#? SimpleApp2.java at line: 235 Dbg-out
variable elapsed SELECT ["+elapsed+"]" );
count = 0;
            beginTiming_ = java.lang.System.currentTimeMillis ();
            while(rs.next())
                {
                //do something with the result set
                for( int i= 1; i <= cols ; i++)
                    {
                    Object o = getData((String)vclass.elementAt(i-1),
                               rs,
                               i);
                    } /* end of for i */
                count++;
                }
            endTiming_ = java.lang.System.currentTimeMillis ();
            printStat();
            elapsed = endTiming_ - beginTiming_;
            System.out.println( "LOOP NO "+j );
            System.out.println( "?#?#? SimpleApp2.java at line: 235 Dbg-out
variable elapsed NEXT ["+elapsed+"]" );
            System.out.println("Counted "+count+" in resultset");
            }


OUPUT WITH ALTERNATIVE 1
------------------------
LOOP NO 0
?#?#? SimpleApp2.java at line: 235 Dbg-out variable elapsed NEXT [3092]
Counted 8 in resultset
?#?#? SimpleApp2.java at line: 235 Dbg-out variable elapsed SELECT [41]
Query Plan: Statement Name:
        null
Statement Text:
SELECT * From SA.UDEVENTDATA WHERE DomainKeyId = ? AND CreationTime < ? AND Name > ?
Parse Time: 0
Bind Time: 0
Optimize Time: 0
Generate Time: 0
Compile Time: 0
Execute Time: 3069
Begin Compilation Timestamp : null
End Compilation Timestamp : null
Begin Execution Timestamp : 2008-04-07 15:50:06.788
End Execution Timestamp : 2008-04-07 15:50:09.95
Statement Execution Plan Text:
Project-Restrict ResultSet (3):
Number of opens = 1
Rows seen = 46372
Rows filtered = 46364
restriction = true
projection = true
        constructor time (milliseconds) = 0
        open time (milliseconds) = 1
        next time (milliseconds) = 3068
        close time (milliseconds) = 0
        restriction time (milliseconds) = 117
        projection time (milliseconds) = 0
        optimizer estimated row count:          505.06
        optimizer estimated cost:        56292.47

Source result set:
        Index Row to Base Row ResultSet for UDEVENTDATA:
        Number of opens = 1
        Rows seen = 46372
Columns accessed from heap = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
                constructor time (milliseconds) = 0
                open time (milliseconds) = 1
                next time (milliseconds) = 2751
                close time (milliseconds) = 25
                optimizer estimated row count:          505.06
                optimizer estimated cost:        56292.47

Index Scan ResultSet for UDEVENTDATA using index UDSOFTOBJECTDATA_DOMAINKEY_IDX_UDEVENTDATA at read committed isolation level using instantaneous share row locking chosen by the optimizer
                Number of opens = 1
                Rows seen = 46372
                Rows filtered = 0
                Fetch Size = 16
                        constructor time (milliseconds) = 0
                        open time (milliseconds) = 3
                        next time (milliseconds) = 417
                        close time (milliseconds) = 25
                        next time in milliseconds/row = 0

                scan information:
                        Bit set of columns fetched=All
                        Number of columns fetched=2
                        Number of deleted rows visited=1
                        Number of pages visited=424
                        Number of rows qualified=46372
                        Number of rows visited=46374
                        Scan type=btree
                        Tree height=3
                        start position:
        >= on first 1 column(s).
        Ordered null semantics on the following columns:

                        stop position:
        > on first 1 column(s).
        Ordered null semantics on the following columns:

                        qualifiers:
None
                        optimizer estimated row count:          505.06
                        optimizer estimated cost:        56292.47



OUPUT WITH ALTERNATIVE 2
------------------------
LOOP NO 0
?#?#? SimpleApp2.java at line: 235 Dbg-out variable elapsed NEXT [36]
Counted 8 in resultset
?#?#? SimpleApp2.java at line: 235 Dbg-out variable elapsed SELECT [0]
Query Plan: Statement Name:
        null
Statement Text:
        CALL SYSCS_UTIL.SYSCS_SET_STATISTICS_TIMING(1)
Parse Time: 1
Bind Time: 0
Optimize Time: 0
Generate Time: 3
Compile Time: 4
Execute Time: -1207579584105
Begin Compilation Timestamp : 2008-04-07 15:46:24.1
End Compilation Timestamp : 2008-04-07 15:46:24.104
Begin Execution Timestamp : 2008-04-07 15:46:24.105
End Execution Timestamp : 2008-04-07 15:46:24.105
Statement Execution Plan Text:
null



QUESTION
--------

Why cannot the prepared statement figure out how to use the indices when statements can, i.e. that domainkey should not be scanned ? How can you make the prepared statement use the same execution plan as the statement so as to return the same type of performance? The problem seems to be Derby specific as MSQL returns adequate performance for ALT 1.

Thanks in advance,






--
Thomas Nielsen

Reply via email to