请解释sql server选择的查询计划

时间:2009-03-12 14:41:05

标签: sql-server indexing

this blog post中,我需要澄清为什么SQL服务器会选择特定类型的扫描:

  

让我们假设为了简单   col1是独一无二的,永远都是   价值增加,col2有1000   不同的价值观和存在   表中的10,000,000行,以及   聚集索引由col1组成,   并且存在非聚集索引   COL2。

     

想象一下查询执行计划   最初为以下创建   传递参数:@ P1 = 1 @ P2 = 99

     

这些值会导致   以下是最佳查询计划   声明使用替代   参数:

     

从t中选择*,其中col1> 1或col2

     
    

99 by col1;

  
     

现在,想象一下查询执行计划   如果初始参数值是:   @ P1 = 6,000,000,@ P2 = 550。

     

和以前一样,最佳查询计划会   替换之后创建   传递参数:

     

从t中选择*,其中col1> 6000000   或col2> 550 by col1;

     

这两个相同的参数化SQL   声明可能会产生   并缓存非常不同的执行   计划由于差异   最初传递参数值。   但是,由于SQL Server只缓存   每个查询一个执行计划,机会   在第一种情况下非常高   查询执行计划将使用   因为聚集索引扫描   'col1> 1'参数替换。   然而,在第二种情况下是查询   执行计划使用索引寻求   最有可能被创造。

来自:http://blogs.msdn.com/sqlprogrammability/archive/2008/11/26/optimize-for-unknown-a-little-known-sql-server-2008-feature.aspx

为什么第一个查询会在第二个查询中使用聚簇索引和索引搜索?

3 个答案:

答案 0 :(得分:1)

假设列只包含正整数:

SQL Server将查看该表的统计信息,并看到,对于第一个查询,表中的所有行都符合col1> 1的条件,因此它选择扫描聚簇索引。

对于第二个查询,相对较小比例的行将满足col1>的标准。 6000000,因此使用索引 seek 可以提高性能。

答案 1 :(得分:1)

如果优化器发现查询中将返回大部分表(例如第一个查询),则执行扫描然后执行搜索会更有效。

如果只返回表的一小部分,例如在第二个查询中,则索引搜索效率更高。

扫描会触及表格中的每一行,无论其是否合格。成本与表中的总行数成比例。如果表很小或者大多数行符合谓词的条件,则扫描是一种有效的策略。

搜索将触及符合条件的行和包含这些符合条件的行的页面,成本与符合条件的行数和页数成比例,而不是与表中的行总数成比例。< / p>

答案 2 :(得分:1)

请注意,在这两种情况下都将使用聚簇索引。在第一个例子中,它是一个聚簇索引SCAN,在第二个例子中,它将是一个聚簇索引SEEK,在大多数情况下,它会像博客作者所说的那样更快。

SQL Server知道聚集索引正在增加。因此,它将在第一种情况下进行聚簇索引扫描。