2009-05-26 21 views
1

以下のMSSQL2005クエリは非常に遅いです。私は彼らがそれをスピードアップする方法でなければならないように感じますが、どのように不明です。私は内部のジョイントを編集してselect文を使って、何が起こっているのかをより明白にしましたが、速度には何の影響もありません(おそらくExecutionプランは同じです)。興味深いことに、実際にはcountvalue以上のキーワードにはkeywordvaluegroupsを使用していませんが、これを利用する方法があるかどうかはわかりません。SQL最適化クエリ

select top 1 cde.processPath as 'keywordValue', count(*) as 'total' 
from dbo.ClientDefinitionEntry AS cde INNER JOIN dbo.KeywordValueGroups AS kvg 
ON cde.keywordGroupId = kvg.keywordValueGrpId 
where kvg.[name] = @definitionName 
group by cde.processPath 
order by total desc  

編集:明らかに、人々は私のサブクエリの使用について不平を言っています。実際、それは違いはありません。私はこの質問を投稿する前にそれらを追加して、何が起こっているのかをより簡単に見られるようにしました。しかし、彼らは物事をもっと混乱させただけなので、私はそれらを使用しないように変更しました。

編集:使用中のインデックス:

ClientDefinitionEntry: 
IX_ClientDefinitionEntry |nonclustered located on PRIMARY|clientId, keywordGroupId 

KeyWordValueGroups 
IX_KeywordValueGroups  |nonclustered located on PRIMARY|keywordValueGrpId 
IX_KeywordValueGroups_2 |nonclustered located on PRIMARY|version 
IX_KeywordValueGroups_Name |nonclustered located on PRIMARY|name 
+0

これらのテーブルのデータ例は、おそらく役に立ちます... –

+0

あなたはどのようなインデックスを用意していますか?彼らは最新ですか? –

+0

私はAndomarとFrederikと間違いなく同意するでしょう - 何らかのDBの変更を開始する前にまず基本的な調査を行うか、またはインデックス作成が必要なものについて何らかの前提を設定してください。そうすれば、不適切なソリューションに時間を浪費する可能性は低くなります。 – Xiaofu

答えて

2

私は次のインデックスがあることを確認したいと思います。

KeywordValueGroupsのIDです。

KeywordValueGroupsの名前。

processPathのINCLUDEを持つClientDefinitionEntryのID。

CREATE INDEX [IX_ClientDefinitionEntry_Id_ProcessPath] ON [dbo].[ClientDefinitionEntry] ([keywordGroupId] ASC) INCLUDE ([processPath]) ON [PRIMARY] 
CREATE INDEX [IX_KeywordValueGroups_Id] ON [dbo].[KeywordValueGroups] ([keywordValueGrpId] ASC) 
CREATE INDEX [IX_KeywordValueGroups_Name] ON [dbo].[KeywordValueGroups] ([name] ASC) 

また、次のようにクエリを変更します。

select top 1 
    cde.processPath as 'keywordValue', 
    count(*) as 'total' 
from 
    dbo.ClientDefinitionEntry AS cde 
INNER JOIN 
    dbo.KeywordValueGroups AS kvg 
ON 
    cde.keywordGroupId = kvg.keywordValueGrpId 
where 
    kvg.[name] = @definitionName 
group by 
    processPath 
order by 
    total desc 
+0

"CREATE INDEX [IX_ClientDefinitionEntry_Id_ProcessPath] ON [dbo]。[ClientDefinitionEntry]([keywordGroupId] ASC)INCLUDE([processPath])ON [PRIMARY]"を使用すると、作業が大幅に高速化しました。私は本当にスピードの点で他のすべてにどのような影響を与えているのか気にしません。 – Brian

+1

その理由は、おそらくidにインデックスがあったにもかかわらず、クエリプランでは、実際のテーブルを検索してprocessPathの値を見つけなければならないことがわかっているからです。 INCLUDEクエリを実行すると、その値が効果的にインデックスに追加されます。索引の物理的なサイズが大きくなり(データベースが大きくなります)、必要なすべてのデータが索引から検索されることを意味します。 –

+0

ええ、これは私のDBクラスから思い出を取り戻しています。 – Brian

3

実行計画のように見えるんどのように? これを見ることで、クエリのどの部分が最も多くの時間/リソースを費やすかを知ることができます。

フィルタリングする列のインデックスを作成しましたか?参加するために使用する列のインデックスを作成しましたか?並べ替えに使用する列のインデックスを作成しましたか?

これを見てもクエリがまだ遅い場合は、データベース/テーブルが断片化されているかどうかを確認して(dbcc showcontig)、インデックスを再構築する必要があるかどうかを確認してください。
インデックスを定期的に再構築する保守計画を立てると便利かもしれません。

3

ランでこのオプションを指定したクエリ:

ON

のSET SHOWPLAN_TEXT質問に結果を追加します。

インデックス、テーブル定義と外部キーに関する
SELECT 
    object_name = Object_Name(ind.object_id), 
    IndexName = ind.name, 
    StatisticsDate = STATS_DATE(ind.object_id, ind.index_id) 
FROM SYS.INDEXES ind 
order by STATS_DATE(ind.object_id, ind.index_id) desc 

と情報が参考になる:あなたの統計情報が最新である場合

も確認してください。

2

確かに知るには十分な情報がありません。その問合せでパフォーマンスの問題が発生している場合は、表にはデータ量が少なく、重要な索引が欠落している必要があります。

どのインデックスが役立つかは、テーブルの大きさと、KeywordGroupIdおよびKeywordValueGrpIdフィールドの値の分布の程度によります。

他の情報が不足しているとすれば、dbo.KeywordValueGroups.[name]と、dbo.ClientDefinitionEntry.[keywordGroupId]がインデックスに登録されていることを確認したいと思います。

クエリが書き込まれる方法のため、dbo.KeywordValueGroups.[keywordValueGrpId]のインデックスだけでは役に立ちませんが、[name], [keywordValueGrpId]のコンポジットインデックスはおそらく役に立ちます。そのインデックスをお持ちの場合は、[name]に専用のインデックスは必要ありません。

だけでは腸感に基づいて、私は[name]上のインデックスは必見であること、そしてcde.keywordGroupIdはおそらく重要であることハザードかもしれません。[name], [keywordValueGrpId]のコンポジットインデックスが役立つかどうかは、同じ[name]を持つレコードの数によって異なります。

確実に知る唯一の方法は、インデックスを追加して何が起こるかを確認することです。

また、このクエリの実行頻度(高速化の重要性)と基礎となるデータの変更頻度について考える必要があります。特定の状況によっては、速度の向上が索引を維持するための追加コストを正当化するとは限りません。

0

ない私たちが話しているレコード数を確認しますが、この:総DESCによって ため が発注を行うことができる前に、すべての行のすべての計算を行う必要があります計算された列の意味です。おそらくこれは遅くなるものの1つですが、私はその特定の問題から脱出することはできません。結合後に少数のレコードしか持たない場合は問題ありませんが、それらのレコードがたくさんある場合はそうかもしれません。

私はまず索引付けに専念します。 foriegnキーを作成すると、自動的に索引付けされないことがよくあります。結合の両方の部分が索引付けされているかどうかを確認します。

パラメータに値を渡すので、パラメータスニッフィングの問題がある可能性もあります。 Googleはそれを修正するための技術です。