2012-11-13 45 views
-3

如果我檢查[deliverybody]字段是否包含'x',以消除具有'x'的行,第一個/非緩存查詢需要很長時間。如果我不檢查'x',[deliverytime]被索引並在第二秒完成查詢。索引字段不會幫助:如何提高查詢時間

With AND [deliverybody] <>'x'部分查詢執行時間爲10+秒,沒有; 1秒。似乎索引字段[deliverytime]不會幫助太多。

查詢只返回1600行。掃描額外的1600個字段需要10+秒。查詢有什麼問題?

更新:從NTEXT升級到NVARCHAR(MAX)。爲保存

此查詢需要10+秒:

SELECT MAX([deliveryid]) AS deliveryid, COUNT(*) AS cnt 
    FROM [_hMaiServer].[dbo].[hm_deliverylog] 
    WHERE [deliverytime] > DATEADD(HOUR, -24, GETDATE()) 
    AND [deliverybody] <> 'x' 
    GROUP BY deliverysubject 

查詢在第二個完成:

SELECT MAX([deliveryid]) AS deliveryid, COUNT(*) AS cnt 
FROM [_hMaiServer].[dbo].[hm_deliverylog] 
WHERE [deliverytime] > DATEADD(HOUR, -2400, GETDATE()) 
--AND [deliverybody] <> 'x' 
GROUP BY deliverysubject 

而且表結構與指標:http://pastebin.com/W0PsDnqS

我的結論:

檢查5000行需要10+秒。較小的{HOUR}值使執行時間更快。如果這是好的,這裏沒有問題,但對我來說似乎很慢。

SELECT COUNT(*) FROM [hm_deliverylog] 
WHERE [deliverybody] <> 'x' 
AND [deliverytime] > DATEADD(HOUR, -__{HOUR}__ , GETDATE())  
+0

列出hm_deliverylog'上的所有索引和它們的列' – RichardTheKiwi

+0

什麼是th輸出'SET STATISTICS IO ON';然後運行每個查詢?和執行計劃? –

+1

[來自MSDN](http://msdn.microsoft.com/zh-cn/library/ms187993.aspx):*重要 在將來的版本中,ntext,文本和圖像數據類型**將被刪除** SQL Server。 **避免在新的開發工作中使用這些數據類型**,並計劃修改當前正在使用它們的應用程序。使用nvarchar(max),varchar(max)和varbinary(max)代替。* –

回答

1

您尚未提供所要求的SET STATISTICS IO ON;結果。然而

一個可能的改進可能,而不是使用

WHERE [deliverybody] <> 'x' 

使用

WHERE NOT (LEN([deliverybody]) = 1 AND LEFT([deliverybody],1) = 'X') 

一個例子,這是低於有益。

CREATE TABLE T1 
    (
    Id    INT, 
    [deliverybody] VARCHAR(MAX) 
) 

INSERT INTO T1 
VALUES  (1, Replicate(Cast('A' AS VARCHAR(MAX)), 2000000000)), 
      (2,'X') 

SET STATISTICS IO ON; 

SELECT id 
FROM T1 
WHERE NOT (Len([deliverybody]) = 1 
      AND LEFT([deliverybody], 1) = 'X') 

SELECT id 
FROM T1 
WHERE [deliverybody] <> 'X' 

DROP TABLE T1 

的IO結果兩者都低於

Table 'T1'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0 
      , lob logical reads 6, lob physical reads 0, lob read-ahead reads 0. 

Table 'T1'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0 
    lob logical reads 2209665, lob physical reads 0, lob read-ahead reads 642255. 

第一個已顯著更少讀取,因爲它避免了在順序拖出整個2GB值地發現,它是不是X

+0

http://pastebin.com/EX17K0GZ檢查長度增加了一點時間。我想我會放棄,並不會檢查'x',我只有5K行,但它需要很長時間...或者我將過濾前100行,它將近100行,因爲過濾' x'字段。 –

+0

@NimeCloud - 實際上那些IO統計看起來並不算太糟糕。每列平均有6個LOB讀取。勞倫斯建議創建一個定義爲'CASE WHEN 1'ELSE 0 END'的CASE WHEN 1 ELSE 0 END'的持久計算列似乎是一個很好的建議,然後在您的查詢中引用該列。 –

+0

我只是從這個子查詢中裁剪AND [deliverybody] <>'x'部分,如果真的有必要,我將在主查詢中使用。比較NVARCHAR(MAX)需要一段時間,我不能索引它,這就是我所學到的。在代碼中,添加另一個表示身體是否爲'x'的列會更好,更快地查詢。感謝您的幫助,非常感謝。 –