0

同じPCからlinq-to-sqlでアクセスされるms-sql-server express 2008にデータベースがあります。(同時アクセスは少ないが、複雑なクエリ)

複数のテーブルがあり、各テーブルが非常に大きくなり、クエリ、削除、更新、および挿入のパフォーマンスが非常に遅くなる可能性があります。

1 つのメイン テーブルプロジェクトがあり、他のほぼすべてのテーブルにプロジェクトがあります。

  • プロジェクトとの直接的な 1 対 n の関係
  • または、プロジェクトと 1 対 n の関係を持つテーブルとの 1 対 n の関係、
  • または、これらのテーブルの 1 つとの 1 対 n の関係などです。

選択、削除、更新、および挿入は、常に 1 つのプロジェクトに対して実行されます。異なるプロジェクト間でエントリを更新したり、2 つのプロジェクトから一致するアイテムを選択したりする必要はありません。

この事実を利用してデータベースのパフォーマンスを向上させる方法はありますか?

該当する場合は、外部キー project_ID に対する非クラスター化インデックスが既にあります。

他にできることはありますか?sql-express でパーティショニングが利用できる場合、パーティショニングは役に立ちますか?


編集:

遅いクエリの例 (言い換えると、ほとんどは linq-to-sql クエリです。いくつかの削除については、SQL を直接実行します):

  delete from items 
  where items.projectID=X 
  AND (items.prop1=a OR items.prop2=b OR items.prop3=c)
  (deletes a few 1000 items, fast when database is empty, slow when lots of other projects exist)

  select top 1 itemprops 
  from itemprops 
  inner join items on items.id = itemprops.itemid 
  inner join project on item.projectid=project.id 
  inner join modes on itemprops.modeId = mode.id
  where item.name = X and project.id = Y and mode.name = z
  (find a certain itemprop corresponding to an item and a mode)


  select top 1 * from foo where projectID=x and name=Y and type=z
  (nonclustered index on projectID + name + type exists)

私のすべてのクエリの共通点は次のとおりですwhere projectID=XY

4

2 に答える 2

0

DBでインデックスやさまざまな設定を試しても、パフォーマンスは大幅に向上しませんでした。

これが最終的に私のために働いたものです:


このタイプのクエリの場合:

 delete from items 
 where items.projectID=X 
 AND (items.prop1=a OR items.prop2=b OR items.prop3=c)

基準に一致するすべてのアイテムを一括削除する代わりに、次を使用して大幅に高速化する方法を見つけました。ON DELETE CASCADE

  1. 新しいダミープロジェクトを作成する
  2. 削除する必要があるすべてのアイテムを更新します。 update items set items.projectID=DummyProjectID where items.projectID=X AND (items.prop1=a OR items.prop2=b OR items.prop3=c)
  3. ダミープロジェクトを削除します。カスケード削除が有効になっているため、これもアイテムを削除しました。

何らかの理由で、これは単にアイテムを削除するよりもはるかに高速です。新しいプロジェクトの作成と数千のアイテムの更新はほぼ瞬時に行われ、プロジェクトの削除は、アイテムを直接削除するよりも少なくとも10倍高速です。


これらのタイプのクエリの場合:

 select top 1 itemprops ...

プロジェクトのすべてのitempropsを一度ディクショナリにロードしてから、このローカルキャッシュからのすべてのクエリに応答する方がはるかに高速でした。あまりエレガントではなく、変更するたびにキャッシュを更新することを忘れないでください。ただし、機能します。

于 2012-05-26T20:49:18.053 に答える
0

最初のステートメント (削除) では、両方の結合フィールドを含む新しい非クラスター化インデックスを作成できます。

CREATE NONCLUSTERED INDEX <MeaningfulIndexName>
ON Items (ProjectID)
INCLUDE (Prop1, Prop2, Prop3)

最後の SELECT クエリについても同様です。オプティマイザーは、このインデックスがより良いプランになることを認識し、それを使用する必要があります。クエリ プランを確認し、そうでない場合はインデックス ヒントを調べます。OR を削除して、3 つの個別の削除クエリを実行することもできます。

最後の 2 つで、必要な TOP をクエリが認識できるように、必ず ORDER BY 句を使用してください。真ん中のものは難しいです: すべてのインデックスを持たない場合 (再度、クエリ プランを確認してください)、その「名前」フィールドでの結合を避け、代わりに ID を使用できるかどうかを確認したい場合があります。常に可能であるとは限りませんが、SQL は文字列よりも数値の比較に優れています。

于 2012-04-28T00:09:29.147 に答える