我要在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子系统的影响较小,而对同时运行的其他查询的影响较小?
还是真的取决于许多变量,例如我拥有的磁盘子系统的类型,索引碎片等等。如果“取决于”,是否有经验法则来解决该问题?