Jus*_*ant 8 sql-server-2008 sql-server
我在 SQL Server 2008 中将一个小表(1,000 行)与一个大表(8M 行)连接起来。连接使用大表上的非聚集覆盖索引,连接可以产生三种可能的查询计划。我试图找出哪个计划更好,但我也想概括这些知识,以便下次我可以更好地了解在查看 SQL I/O 统计信息时使用什么启发式方法。
计划 #1 是一个循环连接,并为大表发出统计信息,如下所示:
Scan count 2582, logical reads 35686, physical reads 1041, read-ahead reads 23052
Run Code Online (Sandbox Code Playgroud)
计划 #2 是一个合并连接并发出如下统计信息:
Scan count 1, logical reads 59034, physical reads 49, read-ahead reads 59004
Run Code Online (Sandbox Code Playgroud)
计划 #3 是一个散列连接并发出如下统计信息:
Scan count 3, logical reads 59011, physical reads 5, read-ahead reads 59010
Run Code Online (Sandbox Code Playgroud)
覆盖索引按 排序(ID, Date)
。查询返回大约 50% 的 ID 的数据,并且对于每个 ID,返回最近 3 个月数据的连续块,通常大约为每个 ID 的 1/4 或行。该查询返回索引中大约 1/8 的总行数。换句话说,查询是稀疏的,但始终如此。
我的假设是,计划 #1 对这种工作负载很糟糕,因为将磁盘磁头移动 2,500 次(甚至 1,041 次)比顺序磁盘扫描要昂贵得多。我还假设#3 和#2 具有相似的顺序(因此更有效)I/O 模式。
但是,是否存在计划 #1 真的是最好的情况,其中“最佳”意味着对 I/O 子系统的影响较小,并且对并发运行的其他查询的影响较小?
或者它真的取决于许多变量,例如我拥有的磁盘子系统类型、索引碎片等。如果“取决于”是否有任何经验法则可以解决问题?
Rem*_*anu 10
这是一个杀手锏:一月份,购买 864* GB * 的 RAM花费了 12,000 美元。通过简单地将服务器的 RAM 增加到永远不会进行物理读取的程度(当然是在预热之后),您可以获得很大的收益。
Other than that is really hard to give an black or white opinion about either of those data points you present. Sure plan #1 had most physical reads, but are you positive that all tests were done on similarly warmed up cache? Could it be that #1 warmed up the cache for #2, what is your test methodology to ensure all cases are considered on level ground? Even so, if you shell out $500 and double the RAM, would it matter any more? #1 does have the least logical reads...
But then #2 is probably benefit from a high DOP (that one scan can be parallel). Is the wall-clock time of #2 better that #1 after you added sufficient RAM?
这些计划中有多少是并行运行的?是否有数十个查询同时请求为 #3 的哈希分配大量内存,从而为 RESOURCE_SEMAPHORE 产生争用?#2 是否在进行排序并请求内存授予?#1 是否会更好地工作,因为它不需要授权(至少从发布的信息来看...)?
真的是相对的,你问的问题更像是为复杂的方程组找到一个解决方案……可能有更多的解决方案。
有一点是肯定的:8M 行应该适合 RAM 并有足够的空闲空间。那些物理读取正在乞求某些存储库。
归档时间: |
|
查看次数: |
6060 次 |
最近记录: |