2011-02-01 21 views
0

に私は、この定義を持つユーザーの変更をログに記録するテーブルを持っている:大きなテーブルの上にntext型の列上のパフォーマンスの低下フィルタリング

audit_trail 
(
    change_id int identity (1, 1) NOT NULL, 
    change_date datetime NOT NULL, 
    user_id int NOT NULL, 
    record_id int NOT NULL, 
    table_name nvarchar(50) NOT NULL, 
    field_name nvarchar(50) NOT NULL, 
    new_value ntext NULL 
) 

このクエリは、このテーブルの上に非常に遅い(15+分)を実行します:

SELECT DISTINCT record_id 
FROM audit_trail 
WHERE table_name = 'jobs' 
    AND field_name = 'status' 
    AND new_value LIKE '157' 

私のテーブルには7000万を超えるレコードがあります。これは、このテーブルの通常のクエリではありません。このテーブルの通常のクエリは、日付別に並べ替えたり、日付範囲の変更を検索したりするため、change_date列にクラスタードインデックスがあります。このクエリの実行計画は、クラスタ化インデックススキャンを実行していることを示しています。私は(table_name, field_name)にノンクラスタード・インデックスを追加してパフォーマンスを向上させることができると考えましたが、このインデックスは使用されていませんでした。このクエリのパフォーマンスを改善するための推奨事項はありますか?

+0

パターンでワイルドカードを使用していないのはなぜですか? – ThomasMcLeod

+0

@ThomasMcLeod new_valueはntext列です。文字列の比較には '='は使用できません。 – InvisibleBacon

+0

私は、パフォーマンスのヒットがntext列と関係していると考えています。この列の選択性は何ですか?実験として、テーブルをntextの代わりにnvarcharでduppし、再度クエリを実行してみてください。 – ThomasMcLeod

答えて

0

次のことを試してください。

sp_tableoption N'audit_trail', 'text in row', '1024' 

あなたは可能性もfull-text search consder。

+0

1024バイトを制限として提案する特別な理由はありますか?私は "行内のテキスト"が挿入/更新/読み込みのパフォーマンスを助けることができますが、私はフィルターが列が使用されているときに改善について多くを読んでいないことを読んだ。この上の任意のリソース? – InvisibleBacon

+0

@invis、ちょうど丸い2進数ではありません。読取りパフォーマンスは、問合せを改善するためのものです。 – ThomasMcLeod

+0

私はすぐにいくつかのテストを実行します。これが役立つかどうかをお知らせします。 – InvisibleBacon

0

これを行うことができれば、nvarcharをvarcharに変更すると、テーブルのサイズとおそらくパフォーマンスが向上します。また、不必要な「DISTINCT」を削除すると、オプティマイザは他のインデックスを使用できるようになります。

+0

私は列の種類を変更できません。うーん..それは違いがあるかどうかを確認するためにDISTINCTを使わずにクエリを試してみる必要があります。このクエリーは同じレコードを複数回返す可能性があるため、実際には不要ではありません。 – InvisibleBacon

+0

私はそれがSOのために簡略化されたと仮定しますが、あなたのサンプルでは、​​DISTINCTは必要ないようです。 –

関連する問題