0

我有这个查询需要很长时间,部分原因是表中的记录数超过了 500 000 条记录,但是我必须使用的连接减慢了很多,至少在我看来

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 而不是负值。

所以我的问题是:我可以做得比我已经拥有的更好吗???我打算把它放在一个视图中,如果这会有所作为。

4

2 回答 2

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
于 2013-08-02T13:18:35.107 回答
0

您还可以尝试使用窗口函数 (ROW_NUMBER) 的 CTE(通用表表达式):

;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
于 2013-08-02T14:26:40.900 回答