相同查询使用不同的索引?

时间:2009-06-30 08:36:32

标签: sql sql-server sql-server-2005 indexing

如果更改where条件的值,选择查询是否可以使用不同的索引?

以下两个查询使用不同的索引,唯一的区别是the的值 condition和typeenvoi ='EXPORT'或typeenvoi ='MAIL'

select numenvoi,adrdest,nomdest,etat,nbessais,numappel,description,typeperiode,datedebut,datefin,codeetat,codecontrat,typeenvoi,dateentree,dateemission,typedoc,numdiffusion,nature,commentaire,criselcomp,crisite,criservice,chrono,codelangueetat,piecejointe, sujetmail, textemail
            from v_envoiautomate
            where etat=0 and typeenvoi='EXPORT'
            and nbessais<1 


select numenvoi,adrdest,nomdest,etat,nbessais,numappel,description,typeperiode,datedebut,datefin,codeetat,codecontrat,typeenvoi,dateentree,dateemission,typedoc,numdiffusion,nature,commentaire,criselcomp,crisite,criservice,chrono,codelangueetat,piecejointe, sujetmail, textemail
            from v_envoiautomate
            where etat=0 and typeenvoi='MAIL'
            and nbessais<1

有人可以给我一个解释吗?

3 个答案:

答案 0 :(得分:9)

索引的详细信息在中的直方图类型数据集中存储为 statistics

每个索引都会分为多个范围,每个范围都包含该范围内关键值的摘要,例如:

  • 范围高值
  • 范围内的值数
  • 范围内的不同值的数量(基数)
  • 等于高值的值的数量

......等等。

您可以使用以下命令查看给定索引的统计信息:

DBCC SHOW_STATISTICS(<tablename>, <indexname>)

每个索引都有一些特性,如密度,最终 selective ,它们告诉查询优化器索引中每个值的唯一性,以及如何这个指数有效地快速定位记录。

由于您的查询在where子句中有三列,因此这些列中的任何一列都可能具有对优化器有用的索引。如果其他索引的选择性不够高,也可能会考虑主键索引。

最终,它归结为优化器快速判断调用读取每个非聚集索引+书签查找所需的页面读取次数,并与其他值进行比较,而不是进行表扫描。

这些判断依据的统计数据也可能有很大差异;默认情况下,SQL Server仅对任何有效表的行中的一小部分进行采样,因此该索引的选择性可能无法代表整体。如果索引中包含高度非唯一的键,则会出现此问题。

在这种特定情况下,我猜你的typeenvoi索引非常独特。既然如此,收集的统计数据可能向优化者表明其中一个值比另一个值更少,并且选择该指数的可能性增加。

答案 1 :(得分:4)

SQL Server中的查询优化器(与大多数现代DBMS平台一样)使用称为“基于成本的优化”的方法。为此,它使用有关数据库中表的统计信息来估计所需的I / O量。优化器将通过转换通过解析语句生成的基本查询计划来考虑它生成的一些语义上等效的查询计划。

根据有关表格的统计数据,通过启发式方法评估每个计划的成本。统计数据有多种形式:

  • 表和索引行计数

  • 分配各列中值的直方图。

如果分布直方图中“MAIL”与“EXPORT”的出现明显不同,则查询优化器可以提出不同的最优计划。这可能就是发生了什么。

答案 2 :(得分:2)

可能与“基数”有关,我相信这个词是表中的值。如果有更多行与该子句匹配,则SQL Server可能会使用不同列的索引来确定一个查询更有效。这是一个极端的情况,但如果有一行匹配'MAIL',它可能会使用该索引。如果表中的每一行都是'EXPORT',但这些'EXPORT'行中只有一半的etat为0,那么它可能会使用该列上的索引。