我在SQLite表中有地理空间数据,带坐标的名称,并为该位置创建了一个rtree,并在名称列上创建了一个普通索引。
根据此文档使用Rtree: http://www.sqlite.org/rtree.html
当我查询特定区域中的记录时,使用rtree并且它可以快速运行:
SELECT demo_data.* FROM demo_data, demo_index
WHERE demo_data.id=demo_index.id
AND minX>=-81.0 AND maxX<=-79.6
AND minY>=35.0 AND maxY>=36.2;
当我只查询名称时,它也会很快,因为使用了名称索引:
SELECT demo_data.* FROM demo_data
WHERE objname="Test"
但是当我将两者结合起来时,它非常慢,似乎整个表都被扫描了:
SELECT demo_data.* FROM demo_data, demo_index
WHERE demo_data.id=demo_index.id
AND objname="Test"
AND minX>=-81.0 AND maxX<=-79.6
AND minY>=35.0 AND maxY>=36.2;
为什么这个组合查询使用两个索引这么慢?
更新
经过对EXPLAIN QUERY PLAN的更多调查后发现,每个条件实际上都使用了索引。但是执行组合查询的时间取决于第一个条件中的记录数。此表demo_data有10mio记录。但如果第一个条件返回大量记录,则组合只会很慢。在这种情况下,有大约1000条记录,objname =“Test”,组合查询需要4秒。 objname =“Test12345”的组合查询,只存在一次,非常快,只有10ms
答案 0 :(得分:1)
涉及多个索引的查询难以加速,可能需要统计信息,甚至可能来自早期查询。
数据库可以(我不知道SQLite实现了什么),例如:
查询优化器的任务是选择最佳策略。如果我们可以预测哪个指数产生较小的结果,通常2或3是最好的。它需要在调用ANALYZE
时获得统计信息。
使用EXPLAIN QUERY PLAN SELECT ...
查看SQLite决定做什么:https://sqlite.org/eqp.html
您还可以尝试嵌套查询以将优化器推向更好的计划,您应该阅读查询优化器文档: https://www.sqlite.org/optoverview.html