0

私はSQLに関する以前の質問からの良い答えに触発されました。現在、このSQLはInterbase2009を搭載したDBで実行されています。サイズは約21GBです。

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

AddrDistanceには840000行、Addressには190000行、DistanceQueryTaskには4行あります。

問題は、これをより速く行うことができるかということです。同じクエリが何度も実行されると思いますが、DistanceQueryTaskからbold_idを選択します。私はストアドプロシージャには興味がなく、単なる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は、データベース内の行の数が少ないことを意味します。

4

4 に答える 4

2

左結合とサブクエリを使用すると、クエリの速度が低下します。

正しいインデックス(Bold_id、DistanceMeters、PseudoDistanceAsCostKm)を使用すると、いくつかの改善を得ることができます。インデックスが多いほど、データベースのサイズが大きくなることに注意してください。

于 2010-03-16T21:55:36.407 に答える
2

bold_idがキーであり、適切にインデックス付けされていると思います。
次に、副選択と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
于 2010-03-16T23:27:11.640 に答える
2

この部分のインデックスを作成します:(DistanceAsMeters=0およびPseudoDistanceAsCostKm=0)これは(不良)テーブルスキャンを実行するためです:ADDRDISTANCE NATURAL

そして、フランソワが述べたように、副選択の代わりに結合を使用してみてください。

于 2010-03-17T06:42:28.343 に答える
2

ダニエルとアンドレが示唆しているように、インデックスは大いに役立ちます。
インデックスの最初の2つの部分は定数であり、次に読み取る必要があるインデックスの小さな部分であるため、このインデックス(DistanceMeters、PseudoDistanceAsCostKm、Bold_id)をお勧めします。

FromAddressやToAddressが存在することが事実である場合は、LEFTJOINをINNERJOINに変更できます。これは、多くの場合、より高速であるためです(クエリオプティマイザはいくつかの仮定を行うことができます)。

于 2010-03-17T09:06:27.290 に答える