2017-08-23 20 views
1

同期の目的で、テーブル内の既存のオブジェクトのサブセットを取得しようとしています。SQLクエリが疎なデータセットでタイムアウトする

このテーブルには、2つのフィールド、[Group]およびMemberがあり、いずれも文字化されたGuidです。

すべての行を合わせて、データテーブルに収まるようにすることもできます。私はすでにOutOfMemory例外が発生しました。しかし、私が今必要としているすべてがデータテーブルにあることを確認する必要があります。だから私はチェックしたいGuids(彼らは1000の塊で来る)を取って、関連するオブジェクトだけを照会します。

ので、代わりにすべての

SELECT * FROM Group_Membership 

で一度私のDataTableを埋めるの私は一度千のGUIDの関連オブジェクトを取得するために私のSQLデータベースに対して次のSQLクエリを実行しています:

SELECT * 
FROM Group_Membership 
WHERE 
    [Group] IN (@Guid0, @Guid1, @Guid2, @Guid3, @Guid4, @Guid5, ..., @Guid999) 

問題のテーブルには合計142個のエントリが含まれ、クエリはすでにタイムアウトしています(CommandTimeout = 30秒)。まばらに埋まっていない他のテーブルでも、同様のクエリはタイムアウトしません。

SQL Serverのロジックと、正しい方向にどのようにヒントできたかについて、誰かが明言してくれましたか?

すでに非クラスタ化インデックスを列Groupに追加しようとしましたが、それは役に立ちませんでした。

+0

テーブルにIDフィールドを追加して、それを使ってthousadnsでレコードを取得できますか? ..where MyField <1000 – GuidoG

答えて

1

WHERE INは、[Group]のインデックスを最大限に使用できるかどうか、またはまったくわからない場合があります。ただし、GUID値を含む2番目の表があり、さらにその列に索引がある場合は、結合が非常に高速に実行される可能性があります。

GUIDの一時テーブルを作成し、それを移入:

CREATE TABLE #Guids (
    Guid varchar(255) 
) 

INSERT INTO #Guids (Guid) 
VALUES 
    (@Guid0, @Guid1, @Guid2, @Guid3, @Guid4, ...) 

CREATE INDEX Idx_Guid ON #Guids (Guid); 

WHERE IN (...)の代わりに結合を使用して、あなたの現在のクエリを言い換えてみてください。これはdoesnの場合、免責事項として

SELECT * 
FROM Group_Membership t1 
INNER JOIN #Guids t2 
    ON t1.[Group] = t2.Guid; 

をあなたのテーブルのカーディナリティが低いため、パフォーマンスが向上する可能性があります。このような場合、インデックスはあまり効果的ではないかもしれません。

+0

私は現在、[一時テーブルを使用してDataTableをロードする方法](https://stackoverflow.com/questions/36501877/sql-server-connection-context-using-temporary)を検索しようとしています。これはちょっと複雑です... – Alexander

+0

@Alexanderおそらくあなたは以前のテンポラリテーブルではあまり働いていなかったのですが...その構文はisn 'セッションが終了したときに消去される点を除いて、通常のテーブルとは異なります。 –

+0

SSMSで同じクエリを実行して、テンポラリテーブルが改善されているかどうかを確認しようとしましたが、元のクエリはSSMSでも数ミリ秒しかかかりませんでした。 SSMSを介して実行される同じクエリが数ミリ秒で返ってくるとき、 'SqlCommand'はどのようにタイムアウトすることができますか? – Alexander

関連する問題