2011-05-02 103 views
2

我檢查,我經常遇到一個緩慢的執行查詢的執行。它顯示了一張大桌子的表掃描。表掃描和索引

下面是查詢:

declare @DateAdded datetime 

set @DateAdded = '5/1/2011' 

SELECT  tblHero.fldHeroName,players.Alliance, 
    tblHero.fldHeroOwner, players.ActIndex, players.fldPlayerCities, 
    tblHero.fldHeroLevel, tblHero.fldHeroPower, 
    players.fldPlayerPrestige, players.fldPlayerName 
FROM   tblHero INNER JOIN 
(
    SELECT  MAX(fldPlayerCities) AS fldPlayerCities, MAX(fldPlayerAlliance) AS  Alliance, 
      MAX(fldPlayerPrestige) AS fldPlayerPrestige, fldPlayerName, 
      MAX(fldPlayerPrestige) - AVG(fldPlayerPrestige) AS ActIndex 
    FROM tblPlayer WHERE (fldPlayerDateAdded >= DATEADD(dd, - 4, @DateAdded)) GROUP BY  fldPlayerName 
) players 
ON tblHero.fldHeroOwner = players.fldPlayerName 
WHERE  (tblHero.fldHeroIsHistoric = 1 or fldHeroLevel = 100) and 
    fldHeroDateAdded = @DateAdded 
ORDER BY players.ActIndex, players.fldPlayerCities, players.fldPlayerPrestige 

從表掃描的謂詞是:

[DBO] [tblHero] [fldHeroDateAdded] = [@ DateAdded] AND([DBO]。 [tblHero] [fldHeroIsHistoric] =(1)或[DBO] [tblHero] [fldHeroLevel] =(100))

以下指數在桌子上:。

CREATE NONCLUSTERED INDEX IX_tblHero_2 ON dbo.tblHero 
    (
    fldHeroDateAdded DESC, 
    fldHeroIsHistoric DESC 
    ) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 
CREATE NONCLUSTERED INDEX IX_tblHero_3 ON dbo.tblHero 
    (
    fldHeroDateAdded DESC, 
    fldHeroLevel DESC 
    ) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,  ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

最後,問題:

我要補充哪些索引擺脫表掃描和速度這件事的?

回答

0

有一對夫婦在這裏posibilities的...

存儲在一個存儲過程的查詢,並索引存儲過程後創建的?如果是這樣,請重新編譯爲存儲過程以強制SQL Server生成新的執行計劃。


否則,它會出現,這是由於在子查詢的連接。如果是這樣,SQL Server在確定(fldPlayerDateAdded >= DATEADD(dd, - 4, @DateAdded))是最重要的謂語。所以它首先生成子查詢結果,然後加入到tblHero表中。這使得至少有兩個選項...

編輯 - 這可能是部分原因是由於ORDER BY子句從子查詢的所有之中。可能嘗試沒有ORDER BY,看看這是否有任何影響。

首先,如果不存在,您可以將(fldPlayerDateAdded,fldPlayerName)上的索引添加到tblPlayer。這可能會允許優化器先過濾tblHero表,然後加入到子查詢中。

此外,要保持基本的執行計劃,但加快步伐,包括在tblHero你的索引字段fldHeroOwner。


注:這可能是有用的,爲您提供完整的實際執行計劃,以更好地確定發生了什麼,以及如何減輕反對。

2

你需要tblPlayer上fldPlayerDateAdded指數是肯定的,因爲它是做一個日期範圍搜索。您也可以嘗試在fldPlayerName上添加單獨的索引。複合索引將執行相同的功能,但會將它們排列在一起,這對於這種情況可能沒有問題,但對於您可能或不可能擁有的所有不同情況而言,並不適合。日期範圍查詢也適用於聚簇索引(一般範圍),但您可能已經在PK上有聚簇索引。

+0

與OP的問題無關,你能否詳細說明'日期範圍查詢也適用於聚簇索引,(一般範圍)''?也就是說,除了一個簡單的事實,即所有索引在聚集時都會獲得更高的性能增益? – MatBailie 2011-05-02 01:11:20

+1

任何範圍查詢更適合聚簇,因爲聚簇索引是有序的。因此,當您在[日期]和[日期2]之間查找10到200之間的日期或日期之前的日期時,由於它們是有序的(索引數據是連續的) ,因此執行速度更快。 – 2011-05-02 02:59:37

+0

問題是肯定的位字段,IsHistoric。如果我從查詢中刪除它,表掃描就會消失。即使單個索引每個字段似乎也沒有什麼區別。 – Darthg8r 2011-05-02 22:17:49

0

您可以在Sql stament的末尾使用OPTION(RECOMPILE)提示,this提示力重新編譯查詢計劃,當SQL語句使用通過脫SP型動物的參數,只是做一個測試這個選項是有用的。