0

同じPCからlinq-to-sqlを使用してアクセスするms-sql-server express 2008のデータベースがあります。 (同時アクセスはほとんどありませんが、複雑なクエリ)'foreign_key = x'クエリのデータベースパフォーマンスを向上させる

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

つのメインテーブルプロジェクトとほぼすべての他のテーブルが

  • プロジェクト
  • 又は1-持つテーブルと1-nの関係に直接1-nの関係有しありプロジェクトとのN関係、
  • 、またはこれらのテーブルのいずれかとの1-n関係などがあります。

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

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

適用可能な場合は、外部キーproject_IDに対して既に非クラスタ化インデックスがあります。

他に何かできますか? sql-expressで使用可能だった場合は、パーティション化が役に立ちますか?


編集:遅いクエリの

例(iは直接SQLを実行するいくつかの削除のために言い換え、最もありLINQツー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を持っています

+0

スロークエリーの1つと関連するスキーマの例を挙げることはできますか? – mwigdahl

+0

メンテナンスジョブを実行していますか? –

+0

re:query 2 - ジョインの列にインデックスがありますか? WHERE句の列はどうでしょうか?クエリ3 - テーブルにいくつのフィールドがあるか(SELECT *を使うのは悪い習慣です - 必要なものだけを選択します) - テーブルは正規化されていますか?また、それが[選択](http://www.akadia.com/services/ora_index_selectivity.html)の場合にのみ有用なインデックスであることを覚えておいてください。 –

答えて

0

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


クエリのこのタイプのために:

ここ

が最後に私のために働いていたものです

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

代わりのバルク条件に一致するすべての項目を削除、私はTHTがある方法を見つけました大幅に高速化、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をロードし、その後、このローカルキャッシュからすべてのクエリに答えるためにはるかに高速でした。あまりエレガントではないので、変更するたびにキャッシュを更新することを忘れてはいけませんが、機能します。

0

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

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

最後のSELECTクエリには同じです。オプティマイザは、この索引がより良い計画をもたらし、それを使用することを認識する必要があります。問合せ計画をチェックし、そうでなければ索引ヒントを調べます。また、ORを削除して3つの個別の削除クエリを実行することもできます。

最後の2つでは、ORDER BY句を使用して、クエリで必要なTOPがわかるようにしてください。真ん中のものは厳しいです。すべてのものにインデックスを付けないと(クエリプランを再度チェックします)、その「名前」フィールドに加わるのを避けてIDを使用することができますか?私はそれが常に可能ではないことを知っていますが、SQLは文字列よりも数値を比較する方が優れています。

+0

私はパーティション分割を使用していませんが、1M +行のような非常に大きなテーブルに対してのみ役立つと言われてきました。 [こちらは](http://www.sqlservercentral.com/articles/partition/64740/)の優れた記事です。 –

関連する問題