我观察到,根据查询,执行完整的表扫描需要不同的时间。我认为,在类似的条件下(select下的一组列,列数据类型),表扫描应该需要一些类似的时间。看起来情况并非如此。我只是想了解这背后的原因。
在查询之前,我使用了"CHECKPOINT">和"DBCC DROPCLEANBUFFERS">以确保查询缓存没有影响。
表格:
- 10列
- 10M行每列具有0.1到0.000001的不同密度
- 无索引
查询:
查询A:返回100行,所用时间:~900ms
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毫秒
我错过了什么?
查询A:(返回100行,耗时:~900ms)
查询B:(返回910595行,所用时间:约15000ms)
我相信您缺少的是在第二个查询中还有大约x100行要获取。这只能解释为什么花了20倍的时间。
这两列的数据密度不同。
查询A,COL07:1000000/10000
查询B,COL05:10000000/10=1000000
两个搜索参数都在数据范围的中间这一事实并不一定会影响搜索速度。这取决于引擎扫描列以返回搜索谓词值的次数。
为了看看情况是否确实如此,我尝试以下方法:
COL04:10000000/1000=10000。WHERE COL04=500上的筛选
COL08:10000000/10000=10000。WHERE COL05=5000 上的过滤
考虑到最初测试的时间,您预计会在约7200ms时看到COL04,在约3600ms时看到COL05。
一篇关于SQL Server COUNT()函数性能比较的有趣文章
全表扫描(也称为顺序扫描)是在数据库上进行的扫描,扫描下的表的每一行都以顺序(串行)顺序读取
参考
在您的情况下,全表扫描按顺序(按顺序)扫描,这样就不需要扫描整个表来推进下一条记录,因为Col7是按顺序扫描的。
但在Query2中,情况并非如此,Col01是随机分布的,因此需要全表扫描。
查询1是乐观扫描,而查询2是悲观扫描。