2

データベースに、都市間の距離を含む巨大なテーブルがあります。これにより、開始都市が選択されたときに、私のアプリケーションは世界中の近くの都市を見つけることができます。

次の 4 つの列が含まれます。

ID, StartCityID, EndCityID, Distance 

約 1 億 2000 万行が含まれています。

、 、両方に別のインデックスstartcityID、 、にそれぞれ別のインデックスを設定しました(これはインデックスを実際に扱うのは初めてなので、正しく行っているかどうかは 100% わかりません)。endcityIDstartcity + distanceendcity + distance

とにかく-次の2つのクエリを実行します。

Select distinct StartCityID
From Distances where EndCityID = 23485

Select distinct EndCityID 
From Distances where StartCityID = 20045

どちらも同じ数の をcityID返しますが、上のものは実行に 35 秒かかり、下のものはすぐに結果を返します。startCityインデックスを見ると、同じように機能するように設定されているendCityようです。

なぜ彼らの行動が違うのか知っている人はいますか?私は途方に暮れています...

注意 - これはより多くの洞察を提供するかもしれませんが、35 秒かかるものです - 同じ ID ですぐにもう一度実行を押すと、その時と同じようにすぐに結果が返されます。

残念ながら、それは私のウェブサイトには十分ではありませんが、役に立つ情報かもしれません.

ありがとう

4

3 に答える 3

1

2つ目はインデックスをカバーしているため、startcityとendcityにインデックスがあるため高速です。

endcityのインデックスは(startcityがないため)カバーしていないため、データを取得するために他のインデックスと結合するか、キールックアップを実行する必要があるため時間がかかります。最初のものはそれを行う必要がなく、データは特定の開始都市の終了都市の順序で並べ替えられます。また、distinctを使用すると、開始都市と終了都市のデータが重複します。重複データがない場合は、distinctを削除します。

チェックしてから、これらの最初の計画は、endcity + distnaceインデックスでのインデックスシークである必要があります。その後、おそらくキールックアップは、endcityの選択性に基づいて、クラスター化されたインデックススキャンである可能性があります。

2つ目は、インデックスの開始都市と終了都市でインデックスシークを行う必要があります。

データがすでにキャッシュにあるため、2回目にすぐに戻ったとおっしゃいました。したがって、以下を試してください

dbcc dropcleanbuffers dbcc freeproccache次に、最初に2番目のクエリを実行します。

注意:PRODサーバーやその他の循環サーバーでは使用しないでください。他のユーザーに影響を与えないマシンで試してください。

于 2012-07-24T09:39:28.093 に答える
0

あなたがしなければならないのはそれについて考えることです...

テーブルに主キーがありますか?それは何ですか?(主キーを持つ)とはどういう意味ですか?DISTINCTキーワードは何を求めていますか?

于 2012-07-24T09:41:25.007 に答える
0

このクエリを試してください(DISTINCTキーワードは避けてください)

Select StartCityID From Distances  group by StartCityID where EndCityID = 23485

Select EndCityID  From Distances  group by EndCityID  where StartCityID = 20045
于 2012-07-24T09:45:35.613 に答える