SQLite 查询性能时间
Posted
技术标签:
【中文标题】SQLite 查询性能时间【英文标题】:SQLite Query Performance Time 【发布时间】:2014-09-18 05:15:06 【问题描述】:我有这个查询需要太多时间(因为最后 1 小时仍在运行)才能执行:
select RL.[LINK_ID] as LINK_ID, RPA.[POSTAL_AREA_ID] as POSTAL_AREA_ID, RRN.[STREET_NAME] as STREET_NAME
from RDF_LINK as RL, RDF_POSTAL_AREA as RPA, RDF_ROAD_LINK as RRL, RDF_ROAD_NAME as RRN
where RRL.[ROAD_NAME_ID] = RRN.[ROAD_NAME_ID]
AND RPA.[POSTAL_AREA_ID] IN (RL.[LEFT_POSTAL_AREA_ID], RL.[RIGHT_POSTAL_AREA_ID])
AND RL.[LINK_ID] = RRL.[LINK_ID]
查询中的所有列都已编入索引。 ANALYZE 命令已经存在。在数据库上执行。 该数据库大约有。 RDF_ROAD_LINK 表中有 7300 万条记录,其他表中有相同数量的记录。
还有其他方法可以编写此查询吗?
EXPLAIN QUERY PLAN
select RL.[LINK_ID] as LINK_ID, RPA.[POSTAL_AREA_ID] as POSTAL_AREA_ID, RRN.[STREET_NAME] as STREET_NAME
from RDF_LINK as RL, RDF_POSTAL_AREA as RPA, RDF_ROAD_LINK as RRL, RDF_ROAD_NAME as RRN
where RRL.[ROAD_NAME_ID] = RRN.[ROAD_NAME_ID]
AND RPA.[POSTAL_AREA_ID] IN (RL.[LEFT_POSTAL_AREA_ID], RL.[RIGHT_POSTAL_AREA_ID])
AND RL.[LINK_ID] = RRL.[LINK_ID]
输出 ::
0 0 3 SCAN TABLE RDF_ROAD_NAME AS RRN
0 1 2 SEARCH TABLE RDF_ROAD_LINK AS RRL USING INDEX IND_ROAD_NAME_ID (ROAD_NAME_ID=?)
0 2 0 SEARCH TABLE RDF_LINK AS RL USING INDEX sqlite_autoindex_RDF_LINK_1 (LINK_ID=?)
0 3 1 SEARCH TABLE RDF_POSTAL_AREA AS RPA USING COVERING INDEX sqlite_autoindex_RDF_POSTAL_AREA_1 (POSTAL_AREA_ID=?)
0 0 0 EXECUTE LIST SUBQUERY 1
【问题讨论】:
叹息。解释查询计划 @CL。 .. 添加了解释查询计划结果...它正在扫描 RDF_ROAD_NAME 表.. 我不知道为什么,尽管 ROAD_NAME_ID 是该表中的主键,而且我在同一列上创建了索引。 【参考方案1】:此查询返回所有 7300 万条记录,并且必须从其他表中查找相应的记录。 这不会很快,因为要缓存的数据太多(而且在这个大小下,甚至索引都可能不适合缓存)。
在两个表之间的连接中,数据库遍历第一个表的所有行,并查找第二个表的相应行。
这意味着第一个表总是以SCAN
结尾,因为使用索引没有意义(当您需要加载所有行时,通过索引不会更快)。
在这种情况下,只有在索引列 (WHERE STREET_NAME = 'My Street'
) 上有附加过滤器,或者结果必须按索引列排序 (ORDER BY ROAD_NAME_ID
) 时,才可能使用 RDF_ROAD_NAME
的索引.
如果表中有很多列未在此查询中使用,您可以使用covering indexes 加快速度(如果您需要的所有数据都已在索引中,则数据库不需要查找相应的表格行):
CREATE INDEX ... ON RDF_ROAD_LINK(ROAD_NAME_ID, LINK_ID);
CREATE INDEX ... ON RDF_LINK(LINK_ID, LEFT_POSTAL_AREA_ID, RIGHT_POSTAL_AREA_ID);
【讨论】:
以上是关于SQLite 查询性能时间的主要内容,如果未能解决你的问题,请参考以下文章