2

テーブルから大量のデータを取得するときに問題があります。

私はデータベーステーブルを持っていますTblJobs。このテーブルには、いくつかの列に大量のデータが含まれています(この列には約60,000文字)。

私のテーブル:

Tblジョブ

JobId   JobTitle     JobDescription 
----------------------------------------------------------------
 1       Job1         TextTextTextTextTextTextTextTextTextTextTextText... (approx 40,000 characters without any space in job description)  
 2       Job2         HelloHelloHelloHelloHelloHelloHelloHelloHelloHell..(approx 60,000 characters without any space  in job description)  
 3       Job3         DemoDemoDemoDemoDemoDemoDemoDemoDemoDemoDemoDemo...(approx 60,000 characters without any space  in job description)  
 4       Job4         TestingTestingTestingTestingTestingTestingTesti....(approx 50,000 characters without any space  in job description)  

テーブルの構造は次のとおりです。

JobId          -  Int
JobTitle       -  VarChar(500)
JobDescription -  VarChar(MAX)

今私の問題は、クエリを実行してすべての列を選択すると、実行TblJobsに時間がかかりすぎることです(約30秒)。これを使って -

Select * from TblJobs

また

Select JobId, JobTitle, JobDescription from TblJobs  

一部のデータをテーブルの列に変更するJobDescriptionと、このクエリはわずか 3 ~ 5 秒で実行されることに驚きました。

変更では、列のデータ間にいくつかのスペースを空けJobDescriptionます。

たとえば、次の表を見ることができます。この表では、jobDescription列間にスペースを入れているだけです (データ型やデータ量は変更していません)。

JobId   JobTitle     JobDescription 
------------------------------------------------------------------------     
 1       Job1         Text TextTextText**<space>**TextTextTextText**<space>**TextTextTextText... (approx 40,000 characters with some space in job description)  
 2       Job2         HelloHello**<space>**HelloHelloHelloHello**<space>**HelloHelloHelloHell..(approx 60,000 characters with some space  in job description)  
 3       Job3         DemoDemoDemoDemo**<space>**DemoDemoDemoDemoDemo**<space>**DemoDemoDemo...(approx 60,000 characters with some space  in job description)  
 4       Job4         TestingTesting**<space>**TestingTestingTesting**<space>**TestingTesti....(approx 50,000 characters with some space  in job description)  

jobdescriptionだから私の質問は、スペースがないときに選択クエリの実行に時間がかかりすぎるのはなぜですか? 私の場合、時間の問題はデータの量に関係ないと思います。

4

3 に答える 3

3

これは、キャッシングの問題である可能性があるようです。簡単に言えば:

  • データはハードドライブに保存されます
  • クエリを受信すると、SQL はデータをハード ドライブ (ディスク) からメモリに読み取り、それを要求したユーザーにメモリから戻します。
  • ディスクからのデータの読み取りは時間的にコストがかかります
  • パフォーマンスを向上させるために、ディスクからメモリに読み取られたデータは「しばらくの間」メモリに残されます</li>
  • このようにすると、同じデータにアクセスする後続のクエリはメモリ内でそれを見つけ、ディスクから再度読み取る必要がなくなります
  • SQL Server では、メモリのこの部分は「バッファ キャッシュ」と呼ばれます</li>
  • Books Online (SQL Server のドキュメント) と他の場所の両方で、これらすべてがどのように機能するかについての広範な記事と議論があります。

したがって、私の理論は次のとおりです。

  • を実行するSelect * from TblJobsと、SQL は関連データをディスクからメモリにロードしました。
  • データを更新すると、最初にメモリ内で更新され、次にディスクに書き戻されます...変更されたデータがメモリに残ります
  • 再度実行Select * from TblJobsすると、データがメモリから直接読み取られます。
  • その最初の読書はまだ非常に長かった. おそらく、@Insac が言ったように、テーブルはハード ドライブ上で断片化されており、読み取るのに「余分な」時間が必要でした。

これをテストするには、コマンドを使用しDBCC DropCleanBuffersます。これにより、バッファ キャッシュがクリアされ、後続のクエリはすべてディスクから読み取る必要があります。そう:

  • 実行DBCC DropCleanBuffersしてバッファをクリアします
  • Select * from TblJobsディスクから直接データを読み取るために実行します。所要時間。
  • Select * from TblJobsそれぞれのタイミングを計りながら、もう一度実行します。これらはメモリから読み取られます
  • 実行DBCC DropCleanBuffersしてバッファを再度クリアします
  • 実行Select * from TblJobsして、ディスクからデータを再度読み取ります。
  • Select * from TblJobsそれぞれのタイミングを計りながら、もう一度実行します。

読み取られるデータの量とマシンに搭載されているメモリの量に大きく依存しますが、最近ではメモリがかなり大きくなっていますが、これは問題にならないと思います。

の連続で混ぜることができますSelect JobId, JobTitle, JobDescription from TblJobs。これはまったく同じデータセットを返し、実行時間に違いはありません。

于 2017-10-27T14:15:57.900 に答える