为什么我的SQL索引被忽略?

前端之家收集整理的这篇文章主要介绍了为什么我的SQL索引被忽略?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们有一个问题,我们的表上的索引被忽略,sql Server 2000正在执行表扫描.我们可以使用WITH(INDEX =< index_name>)子句来强制使用索引,但是不希望这样做.

作为开发人员,我在编写T-sql时非常熟悉sql Server,但是分析和性能调优不是我的强项.我正在寻找任何关于为什么会发生的建议和指导.

更新:

我应该说我们已经重建了所有索引和更新的索引统计信息.

其中一个罪魁祸首的表定义如下:

CREATE TABLE [tblinvoices]
(
    [CustomerID] [int] NOT NULL,[InvoiceNo] [int] NOT NULL,[InvoiceDate] [smalldatetime] NOT NULL,[InvoiceTotal] [numeric](18,2) NOT NULL,[AmountPaid] [numeric](18,2) NULL 
        CONSTRAINT [DF_tblinvoices_AmountPaid]  DEFAULT (0),[DateEntered] [smalldatetime] NULL 
        CONSTRAINT [DF_tblinvoices_DateEntered]  DEFAULT (getdate()),[PaymentRef] [varchar](110),[PaymentType] [varchar](10),[SyncStatus] [int] NULL,[PeriodStart] [smalldatetime] NULL,[DateIssued] [smalldatetime] NULL 
        CONSTRAINT [DF_tblinvoices_dateissued]  DEFAULT (getdate()),CONSTRAINT [PK_tblinvoices] PRIMARY KEY NONCLUSTERED 
    (
        [InvoiceNo] ASC
    ) ON [PRIMARY]
) ON [PRIMARY]

此表上还有一个其他索引(我们希望使用sql):

CustomerID (Non-Unique,Non-Clustered)

以下查询执行表扫描,而不是使用CustomerID索引:

SELECT 
    CustomerID,Sum(InvoiceTotal) AS SumOfInvoiceTotal,Sum(AmountPaid) AS SumOfAmountPaid 
FROM tblInvoices 
WHERE CustomerID = 2112 
GROUP BY customerID

更新:

在回答Autocracy’s question时,这两个查询都执行表扫描.

更新:

在回答Quassnoi’s question关于DBCC SHOW_STATISTICS的数据是:

RANGE_HI_KEY    RANGE_ROWS    EQ_ROWS    DISTINCT_RANGE_ROWS    AVG_RANGE_ROWS
1667            246           454        8                      27.33333
2112            911           3427       16                     56.9375
2133            914           775        16                     57.125

解决方法

最好的做法是通过在CustomerID索引中包含InvoiceTotal和AmountPaid列来使索引成为覆盖索引. (在sql 2005中,您可以将它们添加为“included”列)在sql 2000中,必须将它们添加为其他键列.)如果这样做,我将保证查询优化器将选择您的索引*.

说明:
索引似乎总是有用的,但是使用(不覆盖)索引存在隐藏的成本,也就是“书签查找”,必须完成以检索主要可能需要的任何其他列表.这种书签查找是一项昂贵的操作,并且(一个可能的)原因是查询优化器可能不会选择使用索引.

通过在索引本身中包含所有必需的列,这个书签查找是完全避免的,优化器不必玩这个小游戏,如果使用索引是“值得的”.

(*)或者我将退还您的StackOverflow积分.只要发送一封自封,加盖信封给…

编辑:是的,如果您的主键不是聚集索引,那么一定要做到这一点!但即使是这样的变化,使您的CustomerID索引成为覆盖指数,应该将性能提高一个数量级(10倍或更高)!

猜你在找的MsSQL相关文章