2

datekey列( でありdate、インデックスを持つ)、 である列contentsvarbinary(max)およびである列を含むいくつかの列を持つテーブル mytable がありstringhashますvarchar(100)stringhashと を合わせてテーブルのdatekey主キーを形成します。すべてが私のローカルマシンで実行されています。

ランニング

SELECT TOP 1 * FROM mytable where datekey='2012-12-05'

0 行を返し、0 秒かかります。しかし、datalength条件を追加すると:

SELECT TOP 1 * FROM mytable where datekey='2012-12-05' and datalength(contents)=0

非常に長い時間実行され、待つことをあきらめる前に何も返されません。

私の質問: なぜですか? なぜこれほど長い時間がかかるのか、どうすればわかりますか?


これまでに確認したことは次のとおりです。

「推定実行計画の表示」をクリックすると、非常に時間がかかり、待つことをあきらめる前に何も返されません。

私が行った場合

SELECT TOP 1000 datalength(contents) FROM mytable order by datalength(contents) desc

7 秒かかり、リスト 4228081、4218689 などを返します。

exec sp_spaceused 'mytable'

戻り値

rows        reserved     data         index_size  unused
564019      50755752 KB  50705672 KB  42928 KB    7152 KB

そのため、テーブルは 50 GB と非常に大きくなります。ランニング

SELECT TOP 1000 * FROM mytable

26秒かかります。

sqlservr.exe プロセスは、データベースに設定した制限である約 6 GB です。

4

3 に答える 3

4

クエリはすべての行に対して DATALENGTH を評価する必要があり、最初のレコードを返す前に結果を並べ替える必要があるため、時間がかかります。フィールドの DATALENGTH (またはそれに値が含まれているかどうか) が繰り返しクエリされる可能性が高いものである場合は、結果を保持する追加のインデックス付きフィールド (おそらく永続化された計算フィールド) を提案し、それを検索します。

于 2012-12-07T20:22:37.087 に答える
1

この古いmsdn ブログの投稿datalengthは、行ごとに評価される@MartW の回答と一致しているようです。しかし、「評価された」という言葉の本当の意味と、パフォーマンス低下の本当の原因は何かを理解しておくとよいでしょう。

質問で述べたように、列内のすべての値のサイズcontentsが大きくなる場合があります。これは、最大 8Kb を超えるすべての値が特別な LOB ストレージに格納されることを意味します。そのため、他の列のサイズを考慮すると、テーブルが占有する領域のほとんどがこの LOB ストレージによって占められていることは明らかです。つまり、約 50Gb です。

上記のリンク先の投稿で証明されているように、すべての行の列の長さcontentsが既に評価されている場合でも、LOB に格納されます。そのため、エンジンは引き続き LOB ストレージの一部を読み取ってクエリを実行する必要があります。

クエリの実行時に LOB ストレージが RAM にない場合は、ディスクから読み取る必要がありますが、これはもちろん RAM から読み取るよりもはるかに低速です。また、LOB 部分の読み取りは、ディスクから読み取る必要があるメモリ ブロックの総数を増やす傾向があるため、線形ではなくランダム化されている可能性があります。

于 2017-08-10T13:28:29.623 に答える
0

現時点では、datekey列の前にstringhash列が含まれているため、主キーは使用されない可能性があります。日付キー列のみを含むインデックスを追加してみてください。それでも遅い場合は、そのキーが作成されたら、次のようなクエリヒントを試すこともできます。

SELECT TOP 1 * FROM mytable where datekey='2012-12-05' and datalength(contents)=0 WITH INDEX = IX_datekey

アプリケーションまたは挿入/更新トリガーのいずれかで更新される個別の長さの列を作成することもできます。

于 2012-12-06T11:33:06.620 に答える