SQLite查询性能时间

时间:2014-09-18 05:15:07

标签: sql sqlite

我有这个查询需要花费太多时间(因为最后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

1 个答案:

答案 0 :(得分:1)

此查询返回所有7300万条记录,并且必须从其他表中查找相应的记录。 这可能不会很快,因为要缓存的数据太多(并且使用此大小,甚至索引都不适合缓存)。

在两个表之间的连接中,数据库遍历第一个表的所有行,并查找第二个表的相应行。 这意味着第一个表总是以SCAN结束,因为使用索引是没有意义的(当你需要加载所有行时,通过索引不会更快)。

在这种情况下,只有在索引列(RDF_ROAD_NAME)上有额外的过滤器,或者结果必须按索引列排序时,才可以使用WHERE STREET_NAME = 'My Street'的索引( ORDER BY ROAD_NAME_ID)。

如果表中有许多未在此查询中使用的列,您可以使用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);