1

私が現在の (雇用主の) 会社に入ったとき、新しいデータベース スキーマが設計されました。これは、作成される、または作成される予定の多くのツールのベースとなります。SQL の知識が限られているため、テーブルはかなり適切に設計されていると思います。私の唯一の懸念は、ほぼすべてのテーブルにマルチパートの主キーがあることです。すべてのテーブルには、少なくとも CustomerId と独自のキーがあります。これらは確かに特定のレコードを定義していますが、複数のキー (ここでは 4 倍について話している) は非常に非効率的であると感じています。

今日、2 つのテーブルを結合し、最初のテーブルから 1 つの文字列フィールドを選択してそれらを区別する単純な繰り返しのクエリで、想像を絶するほどの CPU 使用率が発生していました。

select distinct(f.FIELDNAME) as fieldName
from foo f
inner join bar b
   on f.id = b.fId
where b.cId = @id;

実行計画を確認すると (私は EP ヒーローではありません)、3 つの主要な CPU ポイントがあることに気付きました。インデックスに対する個別の (予想どおり) および 2 つのシーク。個人的には、インデックスのシークは非常に高速であるべきだと思いますが、それぞれのコストの 18% を占めています。これは正常ですか?(4 つの) クラスター化インデックスが原因ですか?

--UPDATE--
クエリは Lucene インデックスの作成に使用されます。これは、ほぼ毎週発生する 1 回限りの処理です (矛盾しているように聞こえますが)。私が見る限り、ここで結果を再利用することはできません。

4

3 に答える 3

3

次のクエリを実行して、出力を投稿してください。

SELECT  COUNT(*), COUNT(DISTINCT fieldname)
FROM    foo

SELECT  COUNT(*), COUNT(DISTINCT cId), COUNT(DISTINCT fId)
FROM    bar

これは、どのインデックスがニーズに最も適しているかを見積もるのに役立ちます。

その間、次のインデックスがあることを確認してください。

foo (FIELDNAME)
bar (cId, fId)

クエリを書き直します。

SELECT  DISTINCT(fieldname)
FROM    foo f
WHERE   EXISTS (
        SELECT  1
        FROM    bar b
        WHERE   b.fId = f.id
                AND b.cId = @id
        )

このクエリでは、インデックスを使用してリストf.FIELDNAMEを作成し、インデックスを使用して存在しない値を除外する必要があります。DISTINCTbar

于 2009-05-12T12:21:05.350 に答える
1

この種のクエリはおなじみのようです。私はここで推測していますが、おそらくかなりの打撃を受けているWeb/Winform UIにコンボボックスを設定しています。

おそらく、アプリケーション側で結果をキャッシュして、頻繁に実行しないようにする必要があります。最悪のシナリオでは、これを SQL サーバー側でキャッシュすることもできますが、それは非常に面倒です。

于 2009-05-12T12:29:51.893 に答える
0

ほとんどのデータベースでは、インデックスの最初の列がリストされていない場合、インデックスは使用されません。customerId はすべての主キーの一部であると言いますが、クエリの結合には使用しません。あなたの質問に適切に答えるには、create tablefoo と bar の出力、または少なくともshow index from.

つまり、次のように変更すると、クエリが高速になる可能性があります。

select distinct(f.FIELDNAME) as fieldName
from foo f
inner join bar b
   on f.id = b.fId
   and f.cId = b.cId #Using this part of the key will speed it up
where b.cId = @id;

私のコメントは、主キーが「cId、fId」として順序付けられていることを前提としています。事実上、クエリはすべての cId をチェックする必要はなく、インデックスの一部である cId のみをチェックする必要があります。

于 2009-05-12T13:43:31.573 に答える