2013-08-02 41 views
0

我有這個查詢需要很長時間,部分原因是表中的記錄數量超過了500 000條記錄,但我必須使用的連接減慢了很多,至少我的信仰替換Subselect更有效的東西

SELECT TOP (10) PERCENT H1.DateCompteur, CASE WHEN (h1.cSortie - h2.cSortie > 0)   
THEN h1.cSortie - h2.cSortie ELSE 0 END AS Compte, H1.IdMachine 
FROM dbo.T_HistoriqueCompteur AS H1 INNER JOIN 
    dbo.T_HistoriqueCompteur AS H2 ON H1.IdMachine = H2.IdMachine AND H2.DateCompteur = 
    (SELECT MAX(DateCompteur) AS Expr1 
     FROM dbo.T_HistoriqueCompteur AS HS 
     WHERE (DateCompteur < H1.DateCompteur) AND (H1.IdMachine = IdMachine)) 
ORDER BY H1.DateCompteur DESC 

由於我只需要最新的信息,所以順序很重要。我嘗試在我的子選擇中使用ID字段,因爲它們是按日期定製的,但無法檢測到任何重大改進。

SELECT TOP (10) PERCENT H1.DateCompteur, CASE WHEN (h1.cSortie - h2.cSortie > 0)   
THEN h1.cSortie - h2.cSortie ELSE 0 END AS Compte, H1.IdMachine 
FROM dbo.T_HistoriqueCompteur AS H1 INNER JOIN 
    dbo.T_HistoriqueCompteur AS H2 ON H1.IdMachine = H2.IdMachine AND H2.ID = 
    (SELECT MAX(ID) AS Expr1 
     FROM dbo.T_HistoriqueCompteur AS HS 
     WHERE (ID < H1.ID) AND (H1.IdMachine = IdMachine)) 
ORDER BY H1.DateCompteur DESC 

我使用的表看起來有點像這樣(我有更多的列,但它們在這個查詢中未使用)。

ID bigint 
IdMachine bigint 
cSortie bigint 
DateCompteur datetime 

我想,如果我能擺脫次選擇,我的查詢將運行得更快,但我真的不能找到一個方法來做到這一點。我真正想要做的是使用相同的IdMachine查找前一行,以便計算兩個cSortie值之間的差異。查詢中的情況是因爲它被重置爲0,在這種情況下,我想返回0而不是負值。

所以我的問題是這樣的:我能比我已經有的更好嗎?如果這有所作爲,我打算把它放在一個視圖中。

謝謝。

回答

0

嘗試此查詢

WITH T as 
(
    SELECT TOP (10) PERCENT H1.DateCompteur, H1.cSortie as cSortie1, H1.IdMachine, 
    (
     SELECT TOP 1 H2.cSortie 
     FROM dbo.T_HistoriqueCompteur H2 
     WHERE (H2.DateCompteur < H1.DateCompteur) AND (H1.IdMachine = H2.IdMachine) 
     ORDER BY H2.DateCompteur DESC 
) as cSortie2 
    FROM dbo.T_HistoriqueCompteur AS H1 
    ORDER BY H1.DateCompteur DESC 
) 

select DateCompteur, 
     CASE WHEN (cSortie1 - cSortie2 > 0)   
      THEN cSortie1 - cSortie2 
      ELSE 0 END 
      AS Compte, 
     IdMachine 
FROM T 
+0

我試了一下,它實際上是由大約更好的大部分時間2次(3-4次爲你的,而6次爲7次)。但是,有些時候,它實際上比較慢。我不知道爲什麼會發生這種情況。我在想,也許我可以嘗試在插入記錄時插入鏈接的ID。查找ID(在IdMachine = @IdMachine時總是爲MAX(ID))的壓力可能小於在查詢階段嘗試查找ID。我只是不知道它會得到多快。 –

0

您也可以嘗試的CTE(公共表表達式)與窗函數(ROW_NUMBER):

;WITH CTE AS 
(
    SELECT ID,IdMachine,cSortie,ROW_NUMBER() OVER(PARTITION BY h.IdMachine ORDER BY ID ASC) AS [ROW] 
    FROM T_HistoriqueCompteur h 
) 
SELECT 
    TOP (10) PERCENT 
     H1.DateCompteur, 
     CASE WHEN (h1.cSortie - h2.cSortie > 0) THEN h1.cSortie - h2.cSortie 
      ELSE 0 
     END AS Compte, 
     H1.IdMachine 
FROM dbo.T_HistoriqueCompteur AS H1 
INNER JOIN CTE cte on cte.idmachine = h1.idmachine and cte.id = h1.id 
INNER JOIN CTE h2 on h2.idmachine = cte.idmachine and h2.row + 1 = cte.row 
ORDER BY H1.DateCompteur DESC