逻辑读取与扫描计数


8

我要在SQL Server 2008中将一个小表(1,000行)与一个大表(8M行)连接起来。该连接在大表上使用非聚集覆盖索引,并且该连接可以产生三种可能的查询计划。我试图找出哪种计划更好,但我也想对此知识进行概括,以便下次在查看SQL I / O统计信息时可以更好地了解要使用的启发式方法。

计划#1是一个循环联接,并为大型表发出统计信息,如下所示:

Scan count 2582, logical reads 35686, physical reads 1041, read-ahead reads 23052

计划2是合并联接,并发出如下统计信息:

Scan count 1, logical reads 59034, physical reads 49, read-ahead reads 59004

计划3是哈希联接,并发出如下统计信息:

Scan count 3, logical reads 59011, physical reads 5, read-ahead reads 59010

覆盖率索引由排序(ID, Date)。查询返回大约50%的ID的数据,并且对于每个ID,返回最近3个月数据的连续块,通常为每个ID的大约1/4或行。该查询返回索引中总行的约1/8。换句话说,查询是稀疏的,但始终如此。

我的假设是,计划1对于这种工作负载而言是糟糕的,因为将磁盘头移动大约2500次(甚至是1,041次)比顺序进行磁盘扫描要昂贵得多。我还假定#3和#2具有相似的顺序I / O模式(因此效率更高)。

但是,是否存在计划#1真正最佳的情况,“最佳”意味着对I / O子系统的影响较小,而对同时运行的其他查询的影响较小?

还是真的取决于许多变量,例如我拥有的磁盘子系统的类型,索引碎片等等。如果“取决于”,是否有经验法则来解决该问题?


逻辑读取是直接从缓冲池中进行的,而物理读取是从磁盘中进行的,因此您要尽量减少物理读取的数量是


可以将三个查询计划作为图像发布吗?
usr 2012年

Answers:


10

这是杀手deal的交易:1月,购买864 * GB *的RAM的成本为1.2美元。通过简单地增加服务器的RAM到永远不会达到物理读取的程度(当然,在预热之后),您可以获得很多好处。

除此之外,对于您提供的这些数据点中的任何一个,都很难给出黑或白的评价。当然,计划1的物理读取最多,但是您确定所有测试都是在类似预热的缓存上进行的吗?可能是#1预热了#2的缓存,请问您采用什么测试方法来确保所有情况都在公平的基础上考虑?即便如此,如果您掏出500美元并加倍RAM,这会不再重要吗?#1的逻辑读取最少

但是然后#2可能会受益于较高的DOP(一次扫描可以并行进行)。添加足够的RAM后,#2的挂钟时间是否比#1好?

这些计划中有多少并行运行?是否有数十个查询同时请求#3哈希值的大量内存授予,从而为RESOURCE_SEMAPHORE创建竞争?#2是否正在执行排序并请求内存授予?#1是否会更好,因为它不需要资助(至少从发布的信息...开始)?

确实是相对的,您提出的问题更像是为一个复杂的方程组找到一个解决方案……简单地,可能有多个解决方案。

可以确定的一件事是:800万行应在RAM中容纳,并留有足够的空间。这些物理读请求一些存储体。


1

对于这个看似非常简单的查询,优化器将根据其成本模型持续生成最佳计划。成本模型相当准确。因此,我的建议是将选择权留给SQL Server。

第二个建议:使用热缓存来测量所有三个变体的查询持续时间。然后决定。(不要根据读取和扫描等来决定。对您而言重要的是持续时间。)

通常,选择最佳联接类型(或索引)需要了解联接算法的工作方式。这是太多信息,无法在此处发布。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.