sql - 为什么在获取批量数据(没有空间)时SQL查询执行时间过长?

标签 sql database sql-server-2008

从表中获取大量数据时遇到问题。

我有一个数据库表TblJobs,在此表中某些列包含大量数据(此列中大约有 60,000 个字符)。

我的 table :

TblJobs

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 没有任何空间时,为什么选择查询需要很长时间才能执行? 我认为,时间问题与我的案例中的数据量无关。

最佳答案

这听起来可能是缓存问题。简而言之:

  • 数据存储在硬盘上
  • 当有查询到来时,SQL 会将数据从硬盘驱动器(磁盘)读取到内存中,然后将其从内存传回给请求它的用户
  • 从磁盘读取数据的时间成本很高
  • 为了提高性能,从磁盘读取到内存的任何数据都会在内存中保留“一段时间”
  • 这样做后,访问相同数据的后续查询将在内存中找到它,而不必再次从磁盘读取
  • 在 SQL Server 中,这部分内存称为“缓冲区缓存”
  • 在线书籍(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,多次,每次计时。

很大程度上取决于正在读取的数据量以及计算机上有多少内存 - 但是,嘿,现在内存变得相当大,我怀疑这不会成为问题。

您可以混合运行从 TblJobs 中选择 JobId、JobTitle、JobDescription。这将返回完全相同的数据集,并且它不会对您的执行时间产生任何影响。

关于sql - 为什么在获取批量数据(没有空间)时SQL查询执行时间过长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17986578/

相关文章:

python - 不确定为什么我的存储过程不能在 pyodbc 和 SQL Server 之间工作

mysql - BigQuery 表对于 JOIN 来说太大,并且在查询执行期间超出了资源

php - 选择在日期范围内登录的 MySql 行,返回每天的小时数

mysql - ODBC -> MySQL 同步

mysql - 没有创建外键

sql-server - 插入时输出插入和表值

java - 与字符串字段的多对一关系

mysql - 如何附加一个新的结果列来显示该行的 WHERE 子句的结果?

php - MySQL 查询 WordPress 数据库

sql - 如何比较同一个表中的行?