跑步总不起作用

时间:2013-08-29 07:16:43

标签: sql sql-server

这是从Itzik Ben-Gan的书“T-SQL查询”中获取的查询,但似乎不适用于我的2012 db - 尽管我认为脚本中必定存在拼写错误:

-- Isolate top waits
WITH Waits AS
(
  SELECT    wait_type,
            wait_time_s = wait_time_ms / 1000.,
            pct     = 100. * wait_time_ms / SUM(wait_time_ms) OVER(),
            rn      = ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC)
  FROM      sys.dm_os_wait_stats o
  WHERE     wait_type NOT LIKE '%SLEEP%'
  -- filter out additional irrelevant waits
)
SELECT  W1.wait_type, 
        CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
        CAST(W1.pct AS DECIMAL(12, 2)) AS pct--,
        CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct --<<XXX
FROM    Waits AS W1
        JOIN Waits AS W2 --<<XXX
         ON W2.rn <= W1.rn --<<XXX
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct
HAVING  SUM(W2.pct) - W1.pct < 90 -- percentage threshold  --<<XXX
ORDER BY W1.rn;
GO

如果我注释掉标记为XXX的部分,那么它会返回我期望的结果:

enter image description here

如果我运行整个查询,则会导致以下内容重复且列running_pct不正确:

enter image description here

我该如何解决这个问题? 我尝试将AND W2.wait_type <> W1.wait_type添加到ON子句中 - 这有帮助但似乎丢弃了wait_typeCXPACKET


编辑

他应该W1.rn部分中有GROUP BY吗?

1 个答案:

答案 0 :(得分:0)

我联系了Itzik并且他很好地回复了下面的电子邮件 - 这是正确的:

嗨Jason,

我不确定你的查询是什么意思不适合你。 首先,您的查询似乎是我在本书中提供的修改版本。这是本书中的一本,对我来说效果很好:

WITH Waits AS
(
  SELECT
    wait_type,
    wait_time_ms / 1000. AS wait_time_s,
    100. * wait_time_ms / SUM(wait_time_ms) OVER() AS pct,
    ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn,
    100. * signal_wait_time_ms / wait_time_ms as signal_pct
  FROM sys.dm_os_wait_stats
  WHERE wait_time_ms > 0
    AND wait_type NOT LIKE N'%SLEEP%'
)
SELECT
  W1.wait_type,
  CAST(W1.wait_time_s AS NUMERIC(12, 2)) AS wait_time_s,
  CAST(W1.pct AS NUMERIC(5, 2)) AS pct,
  CAST(SUM(W2.pct) AS NUMERIC(5, 2)) AS running_pct,
  CAST(W1.signal_pct AS NUMERIC(5, 2)) AS signal_pct
FROM Waits AS W1
  JOIN Waits AS W2
    ON W2.rn <= W1.rn
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct, W1.signal_pct
HAVING SUM(W2.pct) - W1.pct < 90 -- percentage threshold
    OR W1.rn <= 5
ORDER BY W1.rn;
GO

至于你的版本,在AS pct之后似乎有一个错位的行注释说明符(两个破折号)(见下面突出显示的部分):

WITH Waits AS
(
  SELECT    wait_type,
            wait_time_s = wait_time_ms / 1000.,
            pct     = 100. * wait_time_ms / SUM(wait_time_ms) OVER(),
            rn      = ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC)
  FROM      sys.dm_os_wait_stats o
  WHERE     wait_type NOT LIKE '%SLEEP%'
  -- filter out additional irrelevant waits
)
SELECT  W1.wait_type,
        CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
        CAST(W1.pct AS DECIMAL(12, 2)) AS pct--,
        CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct --<<XXX
FROM    Waits AS W1
        JOIN Waits AS W2 --<<XXX
         ON W2.rn <= W1.rn --<<XXX
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct
HAVING  SUM(W2.pct) - W1.pct < 90 -- percentage threshold  --<<XXX
ORDER BY W1.rn;

删除后,查询似乎运行良好:

WITH Waits AS
(
  SELECT    wait_type,
            wait_time_s = wait_time_ms / 1000.,
            pct     = 100. * wait_time_ms / SUM(wait_time_ms) OVER(),
            rn      = ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC)
  FROM      sys.dm_os_wait_stats o
  WHERE     wait_type NOT LIKE '%SLEEP%'
  -- filter out additional irrelevant waits
)
SELECT  W1.wait_type,
        CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
        CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
        CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct --<<XXX
FROM    Waits AS W1
        JOIN Waits AS W2 --<<XXX
         ON W2.rn <= W1.rn --<<XXX
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct
HAVING  SUM(W2.pct) - W1.pct < 90 -- percentage threshold  --<<XXX
ORDER BY W1.rn;

如果它仍然不适合您,请告诉我您的错误是什么。

干杯, 伊茨克