Python sqlite3 order by需要时间

Python sqlite3 order by需要时间,python,sql,select,sqlite,sql-order-by,Python,Sql,Select,Sqlite,Sql Order By,我在SQLITE3DB中有一些表,它们位于内存映射分区上。我的select语句与此查询计划类似: sqlite3> EXPLAIN QUERY PLAN SELECT sst.prefix, 0 AS pb, sst.rate, sst.rate_n, sst.interval_1, sst.interval_n FROM sch AS sst WHERE sst.i_workbook_id = 989 AND sst.prefix IN ('', '1', '19', '191',

我在SQLITE3DB中有一些表,它们位于内存映射分区上。我的select语句与此查询计划类似:

sqlite3> EXPLAIN QUERY PLAN SELECT sst.prefix, 0 AS pb, sst.rate, 
sst.rate_n, sst.interval_1, sst.interval_n
FROM sch AS sst
WHERE
sst.i_workbook_id = 989 AND 
sst.prefix IN ('', '1', '19', '191', '1919', '19198') AND 
sst.activation_date <= DATETIME('now') AND 
(sst.expiration_date > DATETIME('now') OR sst.expiration_date IS NULL) AND
sst.start_time <= TIME('now') AND 
sst.end_time >= TIME('now');


0|0|0|SCAN TABLE sch AS sst (~185 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
sqlite3> EXPLAIN QUERY PLAN SELECT sst.prefix, 0 AS pb, sst.rate, 
sst.rate_n, sst.interval_1, sst.interval_n
FROM sch AS sst
WHERE
sst.i_workbook_id = 989 AND 
sst.prefix IN ('', '1', '19', '191', '1919', '19198') AND 
sst.activation_date <= DATETIME('now') AND 
(sst.expiration_date > DATETIME('now') OR sst.expiration_date IS NULL) AND
sst.start_time <= TIME('now') AND 
sst.end_time >= TIME('now') order by sst.prefix;     

0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|SEARCH TABLE sch AS sst USING AUTOMATIC COVERING INDEX (i_workbook_id=?) (~7 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|SEARCH TABLE sch AS sst USING AUTOMATIC COVERING INDEX (i_workbook_id=?) (~7 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|USE TEMP B-TREE FOR ORDER BY
sqlite3>解释查询计划选择sst.prefix,0作为pb,sst.rate,
sst.rate\u n,sst.interval\u 1,sst.interval\u n
从sch到sst
哪里
sst.i_工作簿_id=989和
sst.prefix IN(“”,'1','19','191','1919','19198')和
sst.activation\u date DATETIME(“现在”)或sst.expiration\u date为空)和
sst.start_time=时间(“现在”);
0 | 0 | 0 |将表格sch扫描为sst(~185行)
0 | 0 | 0 |执行列表子查询1
现在,如果我添加order,那么他的查询计划会两次命中主表,所需时间比以前长4倍,而表有130万行,但筛选的行只有两行

以下是新的查询计划:

sqlite3> EXPLAIN QUERY PLAN SELECT sst.prefix, 0 AS pb, sst.rate, 
sst.rate_n, sst.interval_1, sst.interval_n
FROM sch AS sst
WHERE
sst.i_workbook_id = 989 AND 
sst.prefix IN ('', '1', '19', '191', '1919', '19198') AND 
sst.activation_date <= DATETIME('now') AND 
(sst.expiration_date > DATETIME('now') OR sst.expiration_date IS NULL) AND
sst.start_time <= TIME('now') AND 
sst.end_time >= TIME('now');


0|0|0|SCAN TABLE sch AS sst (~185 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
sqlite3> EXPLAIN QUERY PLAN SELECT sst.prefix, 0 AS pb, sst.rate, 
sst.rate_n, sst.interval_1, sst.interval_n
FROM sch AS sst
WHERE
sst.i_workbook_id = 989 AND 
sst.prefix IN ('', '1', '19', '191', '1919', '19198') AND 
sst.activation_date <= DATETIME('now') AND 
(sst.expiration_date > DATETIME('now') OR sst.expiration_date IS NULL) AND
sst.start_time <= TIME('now') AND 
sst.end_time >= TIME('now') order by sst.prefix;     

0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|SEARCH TABLE sch AS sst USING AUTOMATIC COVERING INDEX (i_workbook_id=?) (~7 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|SEARCH TABLE sch AS sst USING AUTOMATIC COVERING INDEX (i_workbook_id=?) (~7 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|USE TEMP B-TREE FOR ORDER BY
sqlite3>解释查询计划选择sst.prefix,0作为pb,sst.rate,
sst.rate\u n,sst.interval\u 1,sst.interval\u n
从sch到sst
哪里
sst.i_工作簿_id=989和
sst.prefix IN(“”,'1','19','191','1919','19198')和
sst.activation\u date DATETIME(“现在”)或sst.expiration\u date为空)和
sst.start_time=按sst.prefix排序的时间(“现在”);
0 | 0 | 0 |执行列表子查询1
0 | 0 | 0 |使用自动覆盖索引(i|u工作簿| id=?)将表sch搜索为sst(~7行)
0 | 0 | 0 |执行列表子查询1
0 | 0 | 0 |使用自动覆盖索引(i|u工作簿| id=?)将表sch搜索为sst(~7行)
0 | 0 | 0 |执行列表子查询1
0 | 0 | 0 |使用临时B-树进行订购

有什么想法吗?我做错了什么?

SQLite试图通过在
I\u工作簿\u id
列上创建临时索引来优化第二个查询。 由于无法以更好的方式优化
表达式,因此会多次执行该查找。 (请参阅和文档。)

你能做的就是

  • i\u工作簿id
    列上创建索引;或
  • i\u工作簿\u id
    前缀
    列上创建索引;或
  • 首先在这两个列上创建一个覆盖索引,然后在
    SELECT
    WHERE
    子句中提到的所有其他列上创建一个覆盖索引