简体   繁体   English

使用Interbase优化SQL

[英]Optimize SQL with Interbase

I was inspired by the good answers from my previous question about SQL. 我以前关于SQL的问题给出了很好的答案,这使我深受鼓舞。 Now this SQL is run on a DB with Interbase 2009. It is about 21 GB in size. 现在,此SQL在带有Interbase 2009的数据库上运行。它的大小约为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

There are 840000 rows with AddrDistance 190000 rows with Address and 4 with DistanceQueryTask. 有840000行,AddrDistance有190000行,有Address,有4行有DistanceQueryTask。

The question is, can this be done faster? 问题是,这样做可以更快吗? I guess, the same query is run many times select bold_id from DistanceQueryTask . 我猜,同一查询运行了很多次, 从DistanceQueryTask中选择bold_id Note that I'm not interested in stored procedures, just plain SQL :) 请注意,我对存储过程不感兴趣,只是普通的SQL :)

EDIT1 Here is the current execution plan: 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)))

And yes, DistanceQueryTask is meant to have a low number if rows in the database. 是的,如果数据库中有行,DistanceQueryTask的编号应该很小。

Using Left Join and subqueries will slow down any query. 使用左联接和子查询将减慢任何查询。

You can get some improvements with the correct indexes (on Bold_id, DistanceMeters, PseudoDistanceAsCostKm ) remember that more indexes increase the size of the database 您可以使用正确的索引(在Bold_id,DistanceMeters,PseudoDistanceAsCostKm上)获得一些改进,请记住,更多索引会增加数据库的大小

I suppose bold_id is your key, and thus properly indexed. 我认为bold_id是您的密钥,因此已正确索引。
Then replacing the subselect and the not...in by a join might help the optimizer. 然后用联接替换subselect和not ... in可能对优化程序有帮助。

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

Create an index for this part: (DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0) because it does a (bad) table scan for it: ADDRDISTANCE NATURAL 为此部分创建一个索引:(DistanceAsMeters = 0并且PseudoDistanceAsCostKm = 0),因为它为此进行了(错误)表扫描:ADDRDISTANCE NATURAL

And try to use the join instead of subselect as stated by Francois. 并尝试使用联接而不是Francois所述的子选择。

As Daniel and Andre sugges an index helps a lot. 正如Daniel和Andre所建议的那样,索引很有帮助。
I would suggest this index (DistanceMeters, PseudoDistanceAsCostKm, Bold_id), because the first 2 parts of the index is constant, then its a smal portion of the index that is needed to read. 我建议使用该索引(DistanceMeters,PseudoDistanceAsCostKm,Bold_id),因为该索引的前2个部分是恒定的,因此它是索引中需要读取的小部分。

If it is a fact that FromAddress and/or ToAddress exist you can change the LEFT JOIN to INNER JOIN, because it is often faster (the query optimizer can make some assumptions). 如果存在FromAddress和/或ToAddress的事实,则可以将LEFT JOIN更改为INNER JOIN,因为它通常更快(查询优化器可以做一些假设)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM