代码改变世界

SQLite查询优化的例子

2009-03-07 15:19  竹 石  阅读(3552)  评论(1编辑  收藏  举报

上次讲到了SQLite的查询优化代码中的具体实现,现在来看一下它的几个实例:

  1 #include "stdio.h"
  2 #include "sqlite3.h"
  3 #include <windows.h>
  4 void query(sqlite3 *db,sqlite3_stmt *stmt,char * sql);
  5 
  6 int main(int argc, char **argv)
  7 {
  8     sqlite3 *db;
  9     char *zErr;
 10     int rc;
 11     char *sql;
 12     sqlite3_stmt *stmt=0;
 13     rc = sqlite3_open("memory.db"&db);
 14     if(rc) {
 15         fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
 16         sqlite3_close(db);
 17     }
 18 
 19     //下面是所建的各个表的结构
 20     sql="CREATE TABLE t1 (num int,word TEXT NOT NULL)";
 21     //sql="CREATE TABLE t4 (num INTEGER NOT NULL,word TEXT NOT NULL)";
 22     //sql="CREATE TABLE t3 (num INTEGER NOT NULL,word TEXT NOT NULL)";
 23     rc = sqlite3_exec(db, sql, NULL, NULL, &zErr);
 24     if(rc != SQLITE_OK) {
 25         if (zErr != NULL) {
 26             fprintf(stderr, "SQL error: %s\n", zErr);
 27             sqlite3_free(zErr);
 28         }
 29     }
 30 
 31     //下面是对所以插入进行手动提交,这样可以加快插入速度
 32     //sqlite3_exec(db,"BEGIN",NULL,NULL,&zErr);
 33     //插入1000000条记录
 34     //for (int i=0;i<1000000;i++)
 35     //{
 36     //    sql = sqlite3_mprintf("insert into t1 values(%d,'%s')",i,"goodc");
 37     //    rc = sqlite3_exec(db, sql, NULL, NULL, &zErr);
 38     //}
 39     //sqlite3_exec(db,"COMMIT",NULL,NULL,&zErr);
 40     
 41     sql="create index t1nwindex on t1(num)";
 42     rc=sqlite3_exec(db, sql, NULL, NULL, &zErr);
 43     if(rc != SQLITE_OK) {
 44         if (zErr != NULL) {
 45             fprintf(stderr, "SQL error: %s\n", zErr);
 46             sqlite3_free(zErr);
 47         }
 48     }
 49 
 50     //sql="drop index t1nwindex";
 51     //sql="drop index t3index";
 52     //sql="delete from t2";
 53     rc=sqlite3_exec(db, sql, NULL, NULL, &zErr);
 54     if(rc != SQLITE_OK) {
 55         if (zErr != NULL) {
 56             fprintf(stderr, "SQL error: %s\n", zErr);
 57             sqlite3_free(zErr);
 58         }
 59     }
 60 
 61     printf("查询结果是:\n");
 62     //sql="select * from t1 where num=3000 or num=2000";//有INTEGER PRIMARY KEY,快
 63     //sql="select * from t2 where num=3000 or num=2000";//没有索引,慢
 64     //sql="select * from t3 where num=3000 or num=2000";//有索引,快
 65     
 66     //这里交换位置了,但是结果用的时间想差比较大的原因是,t1是用索引存储的,但是它不是由create index
 67     //而创建的,所以系统还不会把它作为索引处理,所以这两个表就只是无索引的表,在内部优化计算代价只是对它
 68     //进行估计,因为源代码中没有捕获到下面的查询条件,所以都是系统最大值(源代码中有),所以就嵌套顺序没
 69     //变,所以出现下面的差异。
 70     //sql="SELECT count(*) FROM t3, t1 WHERE t1.num = t3.num";//比下面的快,由于内层少
 71     //sql="SELECT count(*) FROM t1, t3 WHERE t1.num = t3.num";//比上面的慢,由于内层多
 72 
 73     //下面这个已经内部实现优化,所以所用时间是相同的
 74     //sql="SELECT * FROM t2, t3 WHERE t2.num = t3.num";//有索引,稍快
 75     //sql="SELECT * FROM t3, t2 WHERE t2.num = t3.num";//同上,内部已经优化
 76 
 77     //sql="select * from t3 where num=8000";//有索引,快
 78     //sql="select * from t1 where num%2=0";//有索引,但不能用,很慢
 79     //sql="select * from t1 where num=8000";//没有索引,慢
 80     
 81     //BETWEEN的转换优化---内部已经实现优化,如果有索引的话快一点
 82     //sql="select count(*) from t2 where word between 'goodl' and 'goodm'";//BETWEEN
 83     //sql="select count(*) from t2 where word >='goodl' and word<'goodm'";//BETWEEN的转换
 84 
 85     //LIKE的转换优化---内部已经实现优化
 86     //sql="select count(*) from t2 where word like 'goodl%'";//有索引不起作用
 87     //sql="select count(*) from t2 where word >='goodl' and word <'goodm'";//如果有索引会更快
 88 
 89     //IN的转换优化---内部没有实现优化,但此时如果可以用索引的话就会很好
 90     //如果不用索引则在这里体现不出IN比OR优,而如果有索引则差别很明显
 91     //sql="select count(*) from t2 where word in('goodllll','goodkkkk','goodaaaa')";
 92     //sql="select count(*) from t2 where word ='goodllll' or word ='goodkkkk' or word='goodaaaa'";
 93 
 94     int start=GetTickCount();
 95     query(db,stmt,sql);
 96     printf("the time has pass:%dms\n",GetTickCount()-start);
 97     sqlite3_close(db);
 98     return 0;    
 99 }
100 
101 void query(sqlite3 *db,sqlite3_stmt *stmt,char * sql){
102     int rc,ncols,i;
103     const char *tail;
104     rc = sqlite3_prepare(db, sql, -1&stmt, &tail);
105     if(rc != SQLITE_OK) {
106         fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
107     }
108     rc = sqlite3_step(stmt);
109     ncols = sqlite3_column_count(stmt); 
110     while(rc == SQLITE_ROW) {    
111         for(i=0; i < ncols; i++) {
112             fprintf(stderr, "'%s' ", sqlite3_column_text(stmt, i));
113         }
114         fprintf(stderr, "\n");
115         rc = sqlite3_step(stmt);
116     }
117 }