db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From DerbyNovice <clars...@ureason.com>
Subject Statement/PreparedStatement performance difference and problem
Date Mon, 07 Apr 2008 15:34:34 GMT

Why is the prepared statement slower than the  unprepared statement?


BACKGROUND
----------
DB as follows:

CREATE TABLE "SA"."UDEVENTDATA"
(
                                 "ID" VARCHAR(100) NOT NULL,
                                 "DOMAINKEYID" VARCHAR(100),
                                 "CREATIONTIME" BIGINT NOT NULL,
                                 "NAME" VARCHAR(32672),
                                *** AND MORE COLUMNS NOT USED IN THIS
EXAMPLE ****
 );

with indices :

CREATE INDEX "SA"."UDSOFTOBJECTDATA_CREATIONTIME_IDX_UDEVENTDATA" ON 
"SA"."UDEVENTDATA" ("CREATIONTIME");
CREATE INDEX "SA"."UDSOFTOBJECTDATA_DOMAINKEY_IDX_UDEVENTDATA" ON 
"SA"."UDEVENTDATA" ("DOMAINKEYID");
CREATE INDEX "SA"."UDSOFTOBJECTDATA_NAME_IDX_UDEVENTDATA" ON 
"SA"."UDEVENTDATA" ("NAME");

and runs as embedded.
DB contains 46000 records with the following properties

DOMAINKEY are 98% same.
NAMEs are all different.
CREATIONTIME 82% different.

PROBLEM STATEMENT
---------------------------------
ALTERNATIVE 1 uses a PreparedStatement with parameters.
ALTERNATIVE 2 mimics a Statement (and indeed a Statement returns the 
same performance)
PreparedStatements (ALTERNATIVE 1) are VERY SLOW because of table scans 
BUT Statements (ALTERNATIVE 2) are QUICK.
This can be seen in the NEXT and SELECT debug statements in the output
section.

JAVA CODE
---------
                Vector rsv containing Names from the table column NAME.

        PreparedStatement ps;

ALTERNATIVE 1 >
 >1        ps = conn.prepareStatement("SELECT * From SA.UDEVENTDATA  WHERE
DomainKeyId = ? AND CreationTime <  ? AND Name  > ? ");
< END 1
        zize = 10;
        beginTiming_ = java.lang.System.currentTimeMillis ();
        for( int j=0;j<zize;j++ )
            {
            String s2 = (String)rsv.elementAt(j) ;
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,





-- 
View this message in context: http://www.nabble.com/Statement-PreparedStatement-performance-difference-and-problem-tp16537511p16537511.html
Sent from the Apache Derby Users mailing list archive at Nabble.com.


Mime
View raw message