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