题
我是从我以前的问题灵感来自很好的答案有关SQL。 现在这个SQL是一个DB与2009年Interbase的是约21 GB的大小运行。
SELECT DistanceAsMeters, AddrDistance.Bold_Id, AddrDistance.Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
Where DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
and not AddrDistance.bold_id in (select bold_id from DistanceQueryTask)
Order By Created Desc
有84万行与AddrDistance 190000行与地址和4 DistanceQueryTask。
的问题是,可以这样做快?我想,同样的查询运行多次选择bold_id从DistanceQueryTask 。请注意,我不感兴趣,在存储过程中,只是简单的SQL:)
<强> EDIT1 强>以下是当前执行计划:
Statement: SELECT DistanceAsMeters, AddrDistance.Bold_Id, AddrDistance.Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
Where DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
and not AddrDistance.bold_id in (select bold_id from DistanceQueryTask)
Order By Created Desc
PLAN (DISTANCEQUERYTASK INDEX (RDB$PRIMARY218))
PLAN SORT (JOIN (JOIN (ADDRDISTANCE NATURAL,ADDRESSFROM INDEX (RDB$PRIMARY234)),ADDRESSTO INDEX (RDB$PRIMARY234)))
和是的,DistanceQueryTask是指具有低的号码,如果在数据库中的行。
解决方案
使用左联接和子查询将任何查询减慢。
您可以得到一些改进,以正确的索引(上Bold_id,DistanceMeters,PseudoDistanceAsCostKm)请记住,更多的索引增加数据库的大小
其他提示
我想bold_id是你的钥匙,因而适当的索引。点击 然后更换子查询和不...在由加入可能有助于优化。
SELECT DistanceAsMeters, Bold_Id, Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
LEFT JOIN DistanceQueryTask ON AddrDistance.bold_id = DistanceQueryTask.bold_id
Where DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
and DistanceQueryTask.bold_id is null
Order By Created Desc
创建此部分的索引:(DistanceAsMeters = 0和PseudoDistanceAsCostKm = 0) 因为它确实(差)表扫描它:ADDRDISTANCE自然科学
和尝试使用由弗朗索瓦规定的加入,而不是子查询中。
作为丹尼尔和Andre sugges索引有很大帮助。结果 我建议这个指数(DistanceMeters,PseudoDistanceAsCostKm,Bold_id),由于第一部件2的索引是恒定的,则其被读取所需的索引的SmaI位部分。
如果这是一个事实,FROMADDRESS和/或存在的toAddress你可以改变LEFT JOIN到INNER JOIN,因为它往往是更快(查询优化器可以作出一些假设)。