diff --git a/manifest b/manifest index 6e7c3aa864..3a6a1a7c83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sasserts\sto\sbtree.c\sthat\scheck\sfor\sthe\scorrect\ssize\sof\svarious\stypedefs\nand\sstructures.\s\sTicket\s#233.\s(CVS\s845) -D 2003-01-24T12:14:20 +C Update\sthe\sspeed.html\sdocumentation.\s\sRecent\soptimizations\shave\smade\sthe\nlibrary\smuch\sfaster.\s(CVS\s846) +D 2003-01-25T14:25:42 F Makefile.in 6606854b1512f185b8e8c779b8d7fc2750463d64 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -150,11 +150,11 @@ F www/nulls.tcl 29497dac2bc5b437aa7e2e94577dad4d8933ed26 F www/omitted.tcl 118062f40a203fcb88b8d68ef1d7c0073ac191ec F www/opcode.tcl 33c5f2061a05c5d227c72b84c080b3bf74c74f8b F www/quickstart.tcl 368d7ef130274307accceb2e21c9fc70bbb0ba65 -F www/speed.tcl 52759968401d81760fc01f9d3ab6242f6d2a7066 +F www/speed.tcl 4d463e2aea41f688ed320a937f93ff885be918c3 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 19221dee5fee4c8800cbae309f009964c8d646a2 -R 5f54a128edf3ccd559b45b128151fef3 +P c7e647d011b086a6e57420850f6bc4f28fcb23ee +R fb265d63c9802489e93e63983e966b97 U drh -Z a3694ca5aa529fbe36a1167d1cb0514e +Z 9cebef5aee83f0a69d880740ef12b3fa diff --git a/manifest.uuid b/manifest.uuid index c51d816a09..b3a89d579e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7e647d011b086a6e57420850f6bc4f28fcb23ee \ No newline at end of file +ed47d162a072a2f98b633cc14f2be1474288d90b \ No newline at end of file diff --git a/www/speed.tcl b/www/speed.tcl index e71c8dd84f..3ca6dfccb0 100644 --- a/www/speed.tcl +++ b/www/speed.tcl @@ -1,7 +1,7 @@ # # Run this Tcl script to generate the speed.html file. # -set rcsid {$Id: speed.tcl,v 1.9 2003/01/18 22:01:07 drh Exp $ } +set rcsid {$Id: speed.tcl,v 1.10 2003/01/25 14:25:42 drh Exp $ } puts {
@@ -31,15 +31,19 @@ conclusions drawn from these experiments: for most common operations.- SQLite 2.7.6 is usually faster than MySQL 3.23.41 (sometimes - more than twice as fast) though for some operations such as - full table scans, it can be as much as 30% slower. + SQLite 2.7.6 is often faster (sometimes + more than twice as fast) than MySQL 3.23.41 + for most common operations.
SQLite does not execute CREATE INDEX or DROP TABLE as fast as the other databases. But this as not seen is a problem because those are infrequent operations.
+ SQLite works best if you group multiple operations together into + a single transaction. +
@@ -52,7 +56,7 @@ The results presented here come with the following caveats: optimization of complex queries involving multiple joins and subqueries.
- These tests are on a relatively small (approximately 10 megabyte) database. + These tests are on a relatively small (approximately 14 megabyte) database. They do not measure how well the database engines scale to larger problems.
PostgreSQL: | 3.658 |
MySQL: | 0.109 |
SQLite 2.7.6: | 7.177 |
SQLite 2.7.6 (nosync): | 0.266 |
PostgreSQL: | 4.373 |
MySQL: | 0.114 |
SQLite 2.7.6: | 13.061 |
SQLite 2.7.6 (nosync): | 0.223 |
SQLite must close and reopen the database file, and thus invalidate -its cache, for each SQL statement. In spite of this, the asynchronous +
+Because it does not have a central server to coordinate access, +SQLite must close and reopen the database file, and thus invalidate +its cache, for each transaction. In this test, each SQL statement +is a separate transaction so the database file must be opened and closed +and the cache must be flushed 1000 times. In spite of this, the asynchronous version of SQLite is still nearly as fast as MySQL. Notice how much slower -the synchronous version is, however. This is due to the necessity of -calling fsync() after each SQL statement.
+the synchronous version is, however. SQLite calls fsync() after +each synchronous transaction to make sure that all data is safely on +the disk surface before continuing. For most of the 13 seconds in the +synchronous test, SQLite was sitting idle waiting on disk I/O to complete.BEGIN;
CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));
-INSERT INTO t2 VALUES(1,298361,'two hundred ninety eight thousand three hundred sixty one');
+INSERT INTO t2 VALUES(1,59672,'fifty nine thousand six hundred seventy two');
... 24997 lines omitted
-INSERT INTO t2 VALUES(24999,447847,'four hundred forty seven thousand eight hundred forty seven');
-INSERT INTO t2 VALUES(25000,473330,'four hundred seventy three thousand three hundred thirty');
+INSERT INTO t2 VALUES(24999,89569,'eighty nine thousand five hundred sixty nine');
+INSERT INTO t2 VALUES(25000,94666,'ninety four thousand six hundred sixty six');
COMMIT;
PostgreSQL: | 5.058 |
MySQL: | 2.271 |
SQLite 2.7.6: | 0.912 |
SQLite 2.7.6 (nosync): | 0.798 |
PostgreSQL: | 4.900 |
MySQL: | 2.184 |
SQLite 2.7.6: | 0.914 |
SQLite 2.7.6 (nosync): | 0.757 |
When all the INSERTs are put in a transaction, SQLite no longer has to -close and reopen the database between each statement. It also does not +close and reopen the database or invalidate its cache between each statement. +It also does not have to do any fsync()s until the very end. When unshackled in this way, SQLite is much faster than either PostgreSQL and MySQL.
-+BEGIN;
+CREATE TABLE t3(a INTEGER, b INTEGER, c VARCHAR(100));
+CREATE INDEX i3 ON t3(c);
+... 24998 lines omitted
+INSERT INTO t3 VALUES(24999,88509,'eighty eight thousand five hundred nine');
+INSERT INTO t3 VALUES(25000,84791,'eighty four thousand seven hundred ninety one');
+COMMIT;
+ +
PostgreSQL: | 8.175 |
MySQL: | 3.197 |
SQLite 2.7.6: | 1.555 |
SQLite 2.7.6 (nosync): | 1.402 |
+There were reports that SQLite did not perform as well on an indexed table. +This test was recently added to disprove those rumors. It is true that +SQLite is not as fast at creating new index entries as the other engines +(see Test 6 below) but its overall speed is still better. +
+ +BEGIN;
SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b<1000;
@@ -175,25 +210,22 @@ SELECT count(*), avg(b) FROM t2 WHERE b>=9900 AND b<10900;
COMMIT;
PostgreSQL: | 3.657 |
MySQL: | 3.368 |
SQLite 2.7.6: | 4.386 |
SQLite 2.7.6 (nosync): | 4.314 |
PostgreSQL: | 3.629 |
MySQL: | 2.760 |
SQLite 2.7.6: | 2.494 |
SQLite 2.7.6 (nosync): | 2.526 |
This test does 100 queries on a 25000 entry table without an index, -thus requiring a full table scan. SQLite is about 20% or 30% slower -than PostgreSQL and MySQL. The reason for this is believed to be -because SQLite stores all data as strings -and must therefore do 5 million string-to-number conversions in the -course of evaluating the WHERE clauses. Both PostgreSQL and MySQL -store data as binary values where appropriate and can forego -this conversion effort. +thus requiring a full table scan. Prior versions of SQLite used to +be slower than PostgreSQL and MySQL on this test, but recent performance +enhancements have increased its speed so that it is now the fastest +of the group.
- -BEGIN;
SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one%';
@@ -204,37 +236,37 @@ SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%one hundred%';
COMMIT;
PostgreSQL: | 15.967 |
MySQL: | 5.088 |
SQLite 2.7.6: | 5.419 |
SQLite 2.7.6 (nosync): | 5.367 |
PostgreSQL: | 13.409 |
MySQL: | 4.640 |
SQLite 2.7.6: | 3.362 |
SQLite 2.7.6 (nosync): | 3.372 |
This test still does 100 full table scans but it uses uses string comparisons instead of numerical comparisions. -SQLite is almost three times faster than PostgreSQL here. But it is -still 15% slower than MySQL. MySQL appears to be very good -at doing full table scans. +SQLite is over three times faster than PostgreSQL here and about 30% +faster than MySQL.
-CREATE INDEX i2a ON t2(a);
CREATE INDEX i2b ON t2(b);
PostgreSQL: | 0.431 |
MySQL: | 0.340 |
SQLite 2.7.6: | 0.814 |
SQLite 2.7.6 (nosync): | 0.675 |
PostgreSQL: | 0.381 |
MySQL: | 0.318 |
SQLite 2.7.6: | 0.777 |
SQLite 2.7.6 (nosync): | 0.659 |
-SQLite is slower at creating new indices. But since creating -new indices is an uncommon operation, this is not seen as a -problem. +SQLite is slower at creating new indices. This is not a huge problem +(since new indices are not created very often) but it is something that +is being worked on. Hopefully, future versions of SQLite will do better +here.
-SELECT count(*), avg(b) FROM t2 WHERE b>=0 AND b<100;
SELECT count(*), avg(b) FROM t2 WHERE b>=100 AND b<200;
@@ -245,19 +277,18 @@ SELECT count(*), avg(b) FROM t2 WHERE b>=499800 AND b<499900;
SELECT count(*), avg(b) FROM t2 WHERE b>=499900 AND b<500000;
PostgreSQL: | 5.369 |
MySQL: | 1.489 |
SQLite 2.7.6: | 1.423 |
SQLite 2.7.6 (nosync): | 1.358 |
PostgreSQL: | 4.614 |
MySQL: | 1.270 |
SQLite 2.7.6: | 1.121 |
SQLite 2.7.6 (nosync): | 1.162 |
-This test runs a set of 5000 queries that are similar in form to -those in test 3. But now instead of being slower, SQLite -is faster than both PostgreSQL and MySQL. +All three database engines run faster when they have indices to work with. +But SQLite is still the fastest.
-BEGIN;
UPDATE t1 SET b=b*2 WHERE a>=0 AND a<10;
@@ -268,10 +299,10 @@ UPDATE t1 SET b=b*2 WHERE a>=9990 AND a<10000;
COMMIT;
PostgreSQL: | 1.740 |
MySQL: | 8.162 |
SQLite 2.7.6: | 0.635 |
SQLite 2.7.6 (nosync): | 0.608 |
PostgreSQL: | 1.739 |
MySQL: | 8.410 |
SQLite 2.7.6: | 0.637 |
SQLite 2.7.6 (nosync): | 0.638 |
@@ -282,44 +313,44 @@ normally a very fast engine. Perhaps this problem has been addressed in later versions of MySQL.
-BEGIN;
-UPDATE t2 SET b=271822 WHERE a=1;
-UPDATE t2 SET b=28304 WHERE a=2;
+UPDATE t2 SET b=468026 WHERE a=1;
+UPDATE t2 SET b=121928 WHERE a=2;
... 24996 lines omitted
-UPDATE t2 SET b=442549 WHERE a=24999;
-UPDATE t2 SET b=423958 WHERE a=25000;
+UPDATE t2 SET b=35065 WHERE a=24999;
+UPDATE t2 SET b=347393 WHERE a=25000;
COMMIT;
PostgreSQL: | 32.118 |
MySQL: | 8.132 |
SQLite 2.7.6: | 4.109 |
SQLite 2.7.6 (nosync): | 3.712 |
PostgreSQL: | 18.797 |
MySQL: | 8.134 |
SQLite 2.7.6: | 3.520 |
SQLite 2.7.6 (nosync): | 3.104 |
As recently as version 2.7.0, SQLite ran at about the same speed as -MySQL on this test. But recent optimizations to SQLite have doubled -speed of UPDATEs. +MySQL on this test. But recent optimizations to SQLite have more +than doubled speed of UPDATEs.
-BEGIN;
-UPDATE t2 SET c='four hundred sixty eight thousand twenty six' WHERE a=1;
-UPDATE t2 SET c='one hundred twenty one thousand nine hundred twenty eight' WHERE a=2;
+UPDATE t2 SET c='one hundred forty eight thousand three hundred eighty two' WHERE a=1;
+UPDATE t2 SET c='three hundred sixty six thousand five hundred two' WHERE a=2;
... 24996 lines omitted
-UPDATE t2 SET c='thirty five thousand sixty five' WHERE a=24999;
-UPDATE t2 SET c='three hundred forty seven thousand three hundred ninety three' WHERE a=25000;
+UPDATE t2 SET c='three hundred eighty three thousand ninety nine' WHERE a=24999;
+UPDATE t2 SET c='two hundred fifty six thousand eight hundred thirty' WHERE a=25000;
COMMIT;
PostgreSQL: | 55.309 |
MySQL: | 6.585 |
SQLite 2.7.6: | 2.474 |
SQLite 2.7.6 (nosync): | 1.800 |
PostgreSQL: | 48.133 |
MySQL: | 6.982 |
SQLite 2.7.6: | 2.408 |
SQLite 2.7.6 (nosync): | 1.725 |
@@ -328,50 +359,53 @@ as MySQL. But now version 2.7.6 is over two times faster than MySQL and over twenty times faster than PostgreSQL.
-+In fairness to PostgreSQL, it started thrashing on this test. A +knowledgeable administrator might be able to get PostgreSQL to run a lot +faster here by tweaking and tuning the server a little. +
+ +BEGIN;
INSERT INTO t1 SELECT b,a,c FROM t2;
INSERT INTO t2 SELECT b,a,c FROM t1;
COMMIT;
PostgreSQL: | 58.956 |
MySQL: | 1.465 |
SQLite 2.7.6: | 2.926 |
SQLite 2.7.6 (nosync): | 1.664 |
PostgreSQL: | 61.364 |
MySQL: | 1.537 |
SQLite 2.7.6: | 2.787 |
SQLite 2.7.6 (nosync): | 1.599 |
-The poor performance of PostgreSQL in this case appears to be due to its -synchronous behavior. The CPU was mostly idle the test run. Presumably, -PostgreSQL was spending most of its time waiting on disk I/O to complete. -I'm not sure why SQLite performs poorly here. It use to be quicker at this -test, but the same enhancements that sped up the UPDATE logic seem to have -slowed down this test. +The asynchronous SQLite is just a shade slower than MySQL on this test. +(MySQL seems to be especially adept at INSERT...SELECT statements.) +The PostgreSQL engine is still thrashing - most of the 61 seconds it used +were spent waiting on disk I/O.
-DELETE FROM t2 WHERE c LIKE '%fifty%';
PostgreSQL: | 1.365 |
MySQL: | 0.849 |
SQLite 2.7.6: | 4.005 |
SQLite 2.7.6 (nosync): | 0.631 |
PostgreSQL: | 1.509 |
MySQL: | 0.975 |
SQLite 2.7.6: | 4.004 |
SQLite 2.7.6 (nosync): | 0.560 |
The synchronous version of SQLite is the slowest of the group in this test, -but the asynchronous version is the fastest. SQLite used about the same -amount of CPU time in both versions; the difference is the extra time needed -to write information to the disk surface. +but the asynchronous version is the fastest. +The difference is the extra time needed to execute fsync().
-DELETE FROM t2 WHERE a>10 AND a<20000;
PostgreSQL: | 1.340 |
MySQL: | 2.167 |
SQLite 2.7.6: | 2.344 |
SQLite 2.7.6 (nosync): | 0.858 |
PostgreSQL: | 1.316 |
MySQL: | 2.262 |
SQLite 2.7.6: | 2.068 |
SQLite 2.7.6 (nosync): | 0.752 |
@@ -380,38 +414,38 @@ PostgreSQL is faster than MySQL. The asynchronous SQLite is, however, faster then both the other two.
- -INSERT INTO t2 SELECT * FROM t1;
PostgreSQL: | 12.672 |
MySQL: | 1.837 |
SQLite 2.7.6: | 3.076 |
SQLite 2.7.6 (nosync): | 1.570 |
PostgreSQL: | 13.168 |
MySQL: | 1.815 |
SQLite 2.7.6: | 3.210 |
SQLite 2.7.6 (nosync): | 1.485 |
-Some older versions of SQLite would show decreasing performance after a -sequence DELETEs followed by new INSERTs. As this test shows, the +Some older versions of SQLite (prior to version 2.4.0) +would show decreasing performance after a +sequence of DELETEs followed by new INSERTs. As this test shows, the problem has now been resolved.
-BEGIN;
DELETE FROM t1;
-INSERT INTO t1 VALUES(1,29676,'twenty nine thousand six hundred seventy six');
+INSERT INTO t1 VALUES(1,10719,'ten thousand seven hundred nineteen');
... 11997 lines omitted
-INSERT INTO t1 VALUES(11999,71818,'seventy one thousand eight hundred eighteen');
-INSERT INTO t1 VALUES(12000,58579,'fifty eight thousand five hundred seventy nine');
+INSERT INTO t1 VALUES(11999,72836,'seventy two thousand eight hundred thirty six');
+INSERT INTO t1 VALUES(12000,64231,'sixty four thousand two hundred thirty one');
COMMIT;
PostgreSQL: | 4.165 |
MySQL: | 1.733 |
SQLite 2.7.6: | 0.652 |
SQLite 2.7.6 (nosync): | 0.465 |
PostgreSQL: | 4.556 |
MySQL: | 1.704 |
SQLite 2.7.6: | 0.618 |
SQLite 2.7.6 (nosync): | 0.406 |
@@ -419,14 +453,14 @@ SQLite is very good at doing INSERTs within a transaction, which probably explains why it is so much faster than the other databases at this test.
--DROP TABLE t1;
DROP TABLE t2; +DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
PostgreSQL: | 0.133 |
MySQL: | 0.014 |
SQLite 2.7.6: | 0.873 |
SQLite 2.7.6 (nosync): | 0.224 |
PostgreSQL: | 0.135 |
MySQL: | 0.015 |
SQLite 2.7.6: | 0.939 |
SQLite 2.7.6 (nosync): | 0.254 |