2017-10-03 5 views
3

以下に示すように、列とインデックスで構成される単純な表があります。ここでselect節にnvarchar(max)列を含めると、実行時間が大幅に増加します

Columns

Indexes

私のインデックスは、SQLデータベースエンジンチューニングadvisor.Itは、すべての列が含まれての勧告に基づき作成されます。

CREATE NONCLUSTERED INDEX [_dta_index_PROPOSAL_PROCESS_12_13243102__K2_K7_K1_3_4_5_6_8_9_10] ON [dbo].[PROPOSAL_PROCESS] 
(
    [PROPOSAL_ID] ASC, 
    [IS_DELETED] ASC, 
    [ID] ASC 
) 
INCLUDE ( [CREATOR_USER_ID], 
    [CREATION_TIME], 
    [LAST_UPDATER_USER_ID], 
    [LAST_UPDATE_TIME], 
    [CURRENT_PROPOSAL_OBJECT], 
    [INTERFACTORING_XML], 
    [OMDM_OUTPUT_XML]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

画像1のチェックイン時に列を追加するたびに、実行時間が大幅に増加します。これは私のテスト結果です。

上記の列が含まれていない場合。

SET STATISTICS IO ON 
SET STATISTICS TIME ON 
CHECKPOINT; 
GO 
DBCC DROPCLEANBUFFERS; 
GO 
DECLARE @DynamicFilterParam_000001 bit = 0, 
     @DynamicFilterParam_000002 bit = null, 
     @EntityKeyValue1 int = 4419;  
SELECT 
    [Extent1].[ID] AS [ID], 
    --[Extent1].[CURRENT_PROPOSAL_OBJECT] AS [CURRENT_PROPOSAL_OBJECT], 
    --[Extent1].[INTERFACTORING_XML] AS [INTERFACTORING_XML], 
    --[Extent1].[OMDM_OUTPUT_XML] AS [OMDM_OUTPUT_XML], 
    [Extent1].[PROPOSAL_ID] AS [PROPOSAL_ID], 
    [Extent1].[CREATOR_USER_ID] AS [CREATOR_USER_ID], 
    [Extent1].[CREATION_TIME] AS [CREATION_TIME], 
    [Extent1].[LAST_UPDATER_USER_ID] AS [LAST_UPDATER_USER_ID], 
    [Extent1].[LAST_UPDATE_TIME] AS [LAST_UPDATE_TIME], 
    [Extent1].[IS_DELETED] AS [IS_DELETED] 
    FROM [dbo].[PROPOSAL_PROCESS] AS [Extent1] 
    WHERE (([Extent1].[IS_DELETED] = @DynamicFilterParam_000001)) AND ([Extent1].[PROPOSAL_ID] = @EntityKeyValue1); 

(54行(複数可)の影響を受ける) 表 'PROPOSAL_PROCESS'。論理走査カウント1は、ロブの物理0読み込み、ロブ先読みは0

(影響を受けた1行(複数可))

を読み出し、論理LOBが0読み込み、先読み55読み出し、物理的には2を読み出し、58読み出し

SQL Server実行時間: CPU時間= 31ミリ秒、経過時間= 16ミリ秒。 SQL Serverの解析およびコンパイル時間: CPU時間= 0 ms、経過時間= 0 ms。

SQL Server実行時間: CPU時間= 0ミリ秒、経過時間= 0ミリ秒。

Iは、前のクエリ

(54行(複数可)の影響を受ける) 表 'PROPOSAL_PROCESS' の句を選択するCURRENT_PROPOSAL_OBJECTを追加した場合。論理走査カウント1は、ロブの物理0読み込み、ロブ先読みは0

(影響を受けた1行(複数可))

を読み出し、論理LOBが0読み込み、先読み55読み出し、物理的には2を読み出し、58読み出し

SQL Server実行時間: CPU時間= 0 ms、経過時間= 545 ms。 SQL Serverの解析およびコンパイル時間: CPU時間= 0 ms、経過時間= 0 ms。

Iは、前のクエリ

(54行(複数可)の影響を受ける) 表 'PROPOSAL_PROCESS' の句を選択するINTERFACTORING_XMLを追加した場合。論理走査カウント1は、ロブの物理376読み出し、ロブ先読みは0

(影響を受けた1行(複数可))

を読み出し、論理ロブ1822読み込み、先読み55読み出し、物理的には2を読み出し、58読み出し

SQL Server実行時間: CPU時間= 47ミリ秒、経過時間= 2415ミリ秒。 SQL Serverの解析およびコンパイル時間: CPU時間= 0 ms、経過時間= 0 ms。

Iは、前のクエリ

(54行(複数可)の影響を受ける) 表 'PROPOSAL_PROCESS' の句を選択するCURRENT_PROPOSAL_OBJECTを追加した場合。論理走査カウント1は、ロブ物理的には944読み出し、ロブ先読みは0

(影響を受けた1行(複数可))

を読み出し、論理ロブは5048読み込み、先読み55読み出し、物理的には2を読み出し、58読み出し

SQL Server実行時間: CPU時間= 47ミリ秒、経過時間= 6912ミリ秒。 SQL Serverの解析およびコンパイル時間: CPU時間= 0 ms、経過時間= 0 ms。

私はこの日の終わりに、6912ミリ秒に直面しています。この恐ろしいパフォーマンスの理由は何ですか?

インデックスが作成されていませんか?これは、大きなサイズのnvarcharを同じテーブルに置くことに起因する悪い設計の結果ですか?事前

編集中

ありがとう:Hereはissue.Iを再生するためのスクリプトは、SQL-フィドルに同じ問題を作成しようとするが、それも1行を挿入しませんでした。

編集2:select句にすべての列を含めて、2行戻すクエリを作成する別のプロポーザルIDを指定すると、実行時間は概ね100 ms程度にとどまります。クエリの実行時間は、行を返します。インデックスとの接続はありません。

+0

また、テーブルddlと統計情報をスクリプト化することもできます(高度なセクションの下でデータベース - >スクリプト - >スクリプト統計を選択してください) – TheGameiswar

+0

これは、あなたが直面している同じ問題を再現することを可能にし、また多くの時間を節約します – TheGameiswar

答えて

1

NVARCHAR(max)は、古いntextデータ型の代わりです。

ntextは、その情報を常にBLOBとして、行の外側に格納します。可能であれば、NVARCHAR(max)は情報を行に格納しようとします。サイズが原因ではない場合、BLOBにテキストが格納されます。

SQL Serverは、BLOBから読み込み可能なnvarcharテキストへの変換を処理しますが、空きではありません。 SQL Serverが行から外れなければならないたびに、それは追加のオーバーヘッドです。

チューニングアドバイザーが効果的にこれを伝えています。最初のクエリ(0)のlob(ラージオブジェクト)読み取りの数と、それに続くものとnvarchar(max)フィールドを参照するものとを比較します。

+0

だから、このひどいパフォーマンスの原因はロブリードだけですか?治療法はありませんか? – erhan355

1

チューニング・アドバイザーをゴスペルにしないでください。ジョブを完了するために生成したプランの推奨事項が表示されます。

テーブルのサイズを効果的に倍増する場合、すべての列の非クラスタ化インデックス。クラスタ化されたインデックス(実際のテーブル)と非クラスタ化インデックスのコピーがあるため。これにより、テーブルに挿入する場合の書き込み量が倍になります。

インデックスを1つのテーブルから選択していて、インデックスのキーのwhere句に2つのカラムがある場合、インデックスはProposal_IDIs_Deletedになります。SET STATISTICS IO ONと実行計画を使って、そこから何をして遊んでいくのか見てみましょう。

リッチー臀部の統計パーサ:http://statisticsparser.com/

+0

したがって、すべての列をinclude句に含めると、データ挿入時に悪影響を及ぼします。代わりに、ProposalIDとIs_Deletedのみで構成されるインデックスを作成する必要がありますか? ところで、私は統計的パーサーを知らなかったので、ありがたいです – erhan355

+0

@ erhan355はい、インデックスは読み込みには最適ですが、書き込みには悪いです。あなたのスキーマを知らずにクエリを見て、私はそれらの2つの列に1つを作成し、それはあなたがフィルタリングしているものです。心配しない、私の好きなツールの1つ:) – dbajtr

+0

私はインデックスを使って実験をしているとき、私は次のコマンドを使うべきですか?それは問題ですか? DBCC FREEPROCCACHE – erhan355

1

ioの統計からの出力を読み取るためgooodされて私はいくつかのインデックスを作成するために足りませんか?これは、大きなサイズのnvarcharを同じテーブルに置くことに起因する悪い設計の結果ですか?すべてのケースで

私は一貫し..but全体的なCPU時間が比較的低いままであることではないの経過時間を見ることができました。..

私のクエリは1ミリ秒から始まり、8000ミリ秒を要した場合、これは時間の合計でありますクエリ/経過時間が、このCPU時間はわずか10ミリ秒ことができる。..

これは、あなたのケースで起こるクエリを実行してみてください、あなたはCPUを待っているクエリが表示されますように思われる。..最後に

、私はあなたのクエリとインデックスには何の問題もありません。あなたが見ている実行時間は、統計情報を待つ

+0

CPUが割り当てられていないため、クエリがアイドル状態で待機していますか?私はあなたが言ったことを完全に得ていませんでした。私が下の行を削除すれば、それは変わるでしょうか? SET STATISTICS IO ON SET STATISTICS TIME ON – erhan355

+0

これは正しいです。クエリを実行してそれらが何であるかを見ることができます。 PLAN EXPLORERには、すべての待機時間または最新バージョンの販売数が表示されます – TheGameiswar

関連する問題