SQL Server 表扫描时间是不是取决于查询?
Posted
技术标签:
【中文标题】SQL Server 表扫描时间是不是取决于查询?【英文标题】:Does SQL Server Table-Scan Time depend on the Query?SQL Server 表扫描时间是否取决于查询? 【发布时间】:2019-01-02 23:12:09 【问题描述】:我观察到,根据查询进行全表扫描所需的时间不同。我相信在类似的条件下(选择下的列集,列数据类型),表扫描应该花费类似的时间。似乎并非如此。我只是想了解这背后的原因。
我在查询之前使用了 "CHECKPOINT" 和 "DBCC DROPCLEANBUFFERS",以确保查询缓存没有影响。
表格:
10 列 10M 行 每列有不同的密度,范围从 0.1 到 0.000001 没有索引查询:
查询 A: 返回 100 行,耗时:~ 900 毫秒
SELECT [COL00]
FROM [TEST].[dbo].[Test]
WHERE COL07 = 50000
查询 B: 返回 910595 行,耗时:~ 15000ms
SELECT [COL00]
FROM [TEST].[dbo].[Test]
WHERE COL01 = 5
** 其中 COL07 列随机填充了 0 到 100000 之间的整数,而 COL01 列随机填充了 0 到 10 之间的整数
花费时间:
查询 A:大约 900 毫秒 查询 B:大约 18000 毫秒我在这里错过了什么?
【问题讨论】:
在第二次测试中要获取大约 x100 多行,这只能解释为什么它需要 20 倍的时间 切换到 count(1) 作为结果。 【参考方案1】:查询A:(返回100行,耗时:~900ms)
查询 B:(返回 910595 行,耗时:~ 15000ms)
我相信您缺少的是在第二个查询中要获取大约 x100 多行。这只能解释为什么要花 20 倍的时间。
【讨论】:
耶!好像是这样。但是我想的是,表扫描不是意味着要遍历实际的行数据吗?如果是这样的话,两个查询都必须遍历所有数据(我的意思是获取数据)。或者在获取过程中是否有单独的成本? 举个例子,我认为我使用了 SELECT [COL07] FROM [TEST].[dbo].[Test] WHERE COL07 = 50000 和 SELECT [COL01] FROM [TEST].[dbo].[Test ] WHERE COL01 = 5 (其行为类似于我所讨论的)现在我选择 where 子句中的任何内容。如果查询必须遍历 where 子句中列的所有值才能找到匹配的行,为什么会有额外的提取成本? 当你找到它们时,它仍然需要对这些行做一些实际的事情,这也需要时间。如果您尝试 Select count(1) from ... 而不是 Select *,这将最大限度地减少每行要完成的处理量,我怀疑时间会更接近。 是的,我用 count(1) 检查过,现在查询 B 只需要很短的时间。我可能需要深入挖掘才能了解那个 something 是什么。谢谢。【参考方案2】:两列的数据密度不同。
查询 A,COL07:10000000/100000 = 100 查询 B,COL05:10000000/10 = 1000000
两个搜索参数都位于数据范围的中间这一事实并不一定会影响搜索速度。这取决于引擎扫描列以返回搜索谓词值的次数。
为了看看是否确实如此,我会尝试以下方法: COL04:10000000/1000 = 10000。过滤 WHERE COL04 = 500 COL08:10000000/10000 = 1000。过滤 WHERE COL05 = 5000
考虑到初始测试的时间,您预计会在 ~7200ms 看到 COL04,在 ~3600ms 看到 COL05。
一篇关于SQL Server COUNT() Function Performance Comparison 的有趣文章
【讨论】:
【参考方案3】:全表扫描(也称为顺序扫描)是对数据库进行的扫描,其中被扫描的表的每一行都按顺序(串行)顺序读取
Reference
在您的情况下,全表扫描按顺序(以有序方式)扫描,因此它不需要扫描整个表来推进下一条记录,因为 Col7 是有序的。
但在Query2中情况并非如此,Col01是随机分布的,所以需要全表扫描。
查询 1 是乐观扫描,而查询 2 是悲观扫描。
【讨论】:
没有一个是订购的以上是关于SQL Server 表扫描时间是不是取决于查询?的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server:本地查询时间与网络查询时间...和锁定