我有一个问题:我在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
)时,性能下降。
答案 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)) --
这些事情可能有助于你