选择什么基础索引

时间:2014-07-08 13:23:30

标签: sql sql-server sql-server-2012 query-optimization

我有一个问题:我在orderid,productid上有一个聚簇索引,在productid上有一个非聚集索引。当我使用以下查询时,它使用productid上的非聚集索引搜索,这是我所期望的:

select orderid, productid 
from Sales.OrderDetails
where productid =1
order by productid

但是,在不更改搜索参数的情况下,我添加了Quantity

select orderid, productid, qty 
from Sales.OrderDetails
where productid =1
order by productid

现在它使用了聚簇索引扫描;当我强制使用非聚集索引(productid)时,性能下降。

3 个答案:

答案 0 :(得分:4)

每个非聚簇索引都将在其叶级节点中包含聚类键。因此,productid上的非聚集索引在其叶级节点中确实包含productid orderid

因此,只需在非聚簇索引中查找值即可满足您的第一个查询 - 找到的叶级节点将包含SELECT所需的两列。

这是 NOT 当您添加其他列时的情况,例如qty - 现在,一旦找到,需要对实际数据页进行密钥查找才能获得所有列从您的SELECT查询返回。因此,现在,聚合索引扫描可能比非聚簇索引搜索和密钥查找表现更好。

我很确定在您的索引中包含 qty列后,第二个查询会再次使用非聚集索引:

CREATE NONCLUSTERED INDEX ix_productId
ON Sales.OrderDetails(productId)
INCLUDE (qty)

因为再次:现在找到非聚集索引中的叶级页面后,该页面上将显示所有必需的列,并且可以返回到第二个查询。

答案 1 :(得分:0)

有意义的是,使用聚簇索引添加qty列是理想的,因为非索引(数据)列位于聚簇索引属性附近。

答案 2 :(得分:0)

索引:"正确的索引将有助于优化人员找到最佳执行计划"

选择性:指数的密度= 1除以不同记录的数量。密度值越小,优化器选择指数的机会越高,选择性越高。对于每个索引,还会有一个统计信息,通过以下DBCC命令,我们可以找到统计信息的选择性和索引的选择性。

DBCC SHOW_STATISTICS('table name','statistics name')

当Clustered index列包含时,它还会显示列的密度。较低的选择性将使优化器忽略该索引。即使在搜索列上创建索引,我们也可能会发现性能低下的查询。原因可能是选择性低。

Eg: 
SELECT sod.OrderQty ,
sod.SalesOrderID ,
sod.SalesOrderDetailID ,
sod.LineTotal
FROM Sales.SalesOrderDetail sod
WHERE sod.OrderQty = 10;

当涉及where条件时,搜索的可能性很高。但在上面的查询中,执行计划显示聚簇索引Scan。在OrderQty上创建了一个非集群索引,仍然优化器忽略了索引。原因是,订单数量密度是1/41不同的值=〜0.25,具有如此低的选择性,optmizser发现它与索引扫描本身相当。

过时的统计数据确实可以使OPTIMIZER忽略索引。

DBA可以采取不同的措施来帮助优化程序找到最佳的执行计划。其中一个是QUERY HINTS。引入Query命中可能会有所帮助,同时也会影响性能。与索引相关的查询提示为WITH(INDEX()) 我们可以告诉优化器使用特定的索引。

    eg: SELECT * FROM table WITH (INDEX (0))            -- Can give index number
        SELECT * FROM table WITH (INDEX (indexName))    --

这些事情可能有助于你