2011-01-28 13 views
5

誰かがこのSQLクエリを調整するのを助けてくれますか?なぜこのSQLはインデックスシークの代わりにインデックススキャンを実行しますか?

SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children, 
     a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID, 
     a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation, 
     a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy 
FROM dbo.NPapplicants AS a INNER JOIN 
     dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID 
WHERE (apt.Offline = 0) 
AND  (apt.MA = 'M') 

実行計画は次のとおりです。

です。私はNPapplicantsのためのインデックススキャンを得ている理由を私は理解していない何

enter image description here

です。私は、BuildingIDとApartmentIDをカバーするインデックスを持っています。それを使うべきではありませんか?

+0

テーブルにはいくつの行がありますか? –

+0

画像は最新の統計情報の更新情報から7775を示します – RichardTheKiwi

答えて

6

これは、マッチから戻ってくる10Kレコードに近いと考えているからです。 10Kキーを使用して他の列を取得するためのデータに戻ることは、少なくとも100Kレコードをスキャンして、ハッシュ一致を使用してフィルタリングすることと同等です。

他のテーブルへのアクセスに関して、クエリオプティマイザはインデックスが有用であると判断しました(おそらくOfflineまたはMAに対して)ので、そのインデックスで結合キーを取得しようとしています。

これらの2つは、最終的な出力を生成するために交差のためにハッシュ照合されます。

+0

応答に感謝します。それで、私ができることはあまりないと言っていますか?そのクエリは、その多くのデータを返すために得られるほど微調整されていますか? – Axeva

+0

申請者のテーブルからのその数量のカラムについては、それは得られるほど良いものです。 'apartment(Offline、MA)'のフィルタがINDEX SEEKをオンにするキーがほんの少ししか生成できないように、本当に選択的(1%以下)と 'count(apartments) RichardTheKiwi

3

インデックスは、B-Treeでの検索は、テーブルスキャン(レコードごと)の数倍です。

また、他の列の値を取得するためには、クラスタード・インデックスの別のシークを行う必要があります。

レコードの大部分が一致すると予想される場合は、クラスタ化インデックスをスキャンするほうが安いです。オプティマイザが最適な方法を選択していた、あなたがこれを実行していることを確認するために

SET STATISTICS IO ON 
SET STATSTICS TIME ON 

SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children, 
     a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID, 
     a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation, 
     a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy 
FROM dbo.NPapplicants AS a INNER JOIN 
     dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID 
WHERE (apt.Offline = 0) 
AND  (apt.MA = 'M') 

SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children, 
     a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID, 
     a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation, 
     a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy 
FROM dbo.NPapplicants WITH (INDEX (index_name)) AS a 
INNER JOIN 
     dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID 
WHERE (apt.Offline = 0) 
AND  (apt.MA = 'M') 

はあなたのインデックスの実際の名前でindex_nameを交換し、実行時間とI/O操作の数を比較(などメッセージのタブに表示されます)

+1

興味深い。索引なし:CPU時間= 93ミリ秒、経過時間= 679ミリ秒。 ///索引付き:CPU時間= 172 ms、経過時間= 666 ms。 – Axeva

+0

@Axeva:あなたが見る通り、ママオプティマイザーは馬鹿を起こさなかった。非選択フィールドでは、特に非カバー索引の場合、索引シークがより高価になります。 – Quassnoi

関連する問題