平均插入率

时间:2012-01-23 18:57:01

标签: sql tsql

我有一个表格,其中有一列表示每行插入表格的日期和时间。我正在尝试获取插入的平均和峰值速率的统计数据:

  • 每分钟峰值插入
  • 每秒峰值插入
  • 每分钟平均插入次数
  • 每秒平均插入次数

我可以设想一个解决方案,使用GROUP BY将数据放入“桶”(每个间隔一个),然后平均每个区域中的项目数,但这似乎是一个非常笨重的解决方案。

这个问题是否有更优雅的T-SQL解决方案?

3 个答案:

答案 0 :(得分:4)

分组集是要走的路,它们适用于在一个查询中通过多组分组属性(分组集)进行分组的应用程序,并且应该会产生更好的执行计划即更好的表现:

-- if you weren't grouping by minutes and seconds this would
-- probably look more 'elegant'
SELECT      
    GROUPING_ID(
        YEAR(orderdate), 
        MONTH(orderdate), 
        DAY(orderdate), 
        DATEPART(hour, orderdate),
        DATEPART(MINUTE, orderdate),
        DATEPART(SECOND, orderdate)) AS grp_id,
    MAX([Insertions])                AS max_insertions,
    AVG([Average])                   AS avg_insertions,
    YEAR(orderdate)                  AS order_year,
    MONTH(orderdate)                 AS order_month, 
    DAY(orderdate)                   AS order_day, 
    DATEPART(HOUR, orderdate)        AS order_hour,
    DATEPART(MINUTE, orderdate)      AS order_minute,
    DATEPART(SECOND, orderdate)      AS order_second -- this will be null if the grouping set is minute
FROM Sales.Orders
GROUP BY
   GROUPING SETS
   (
       (
            -- grouping set 1: order second
            YEAR(orderdate), 
            MONTH(orderdate), 
            DAY(orderdate), 
            DATEPART(hour, orderdate),
            DATEPART(MINUTE, orderdate),
            DATEPART(SECOND, orderdate)
        ),
        (
            -- grouping set 2: order minute
            YEAR(orderdate), 
            MONTH(orderdate), 
            DAY(orderdate), 
            DATEPART(hour, orderdate),
            DATEPART(MINUTE, orderdate)
        )
    );

答案 1 :(得分:2)

GROUP BY是要走的路。

我会为你想要的每个时间间隔制作一个CTE,并为每个时间间隔选择最大值:

;WITH CTEMinute AS
(
    SELECT  YEAR(datefield) yr, 
            MONTH(datefield) mo, 
            DAY(datefield) d, 
            DATEPART(hour, datefield) hr, 
            DATEPART(minute, datefield) Mint, 
            COUNT(*) as 'Inserts'
    FROM MyTable
    GROUP BY    YEAR(datefield), 
                MONTH(datefield), 
                DAY(datefield), 
                DATEPART(hour, datefield), 
                DATEPART(minute, datefield)
)
,CTESecond AS
(
    SELECT YEAR(datefield) yr, 
            MONTH(datefield) mo, 
            DAY(datefield) d, 
            DATEPART(hour, datefield) hr, 
            DATEPART(minute, datefield) Mint, 
            DATEPART(second, datefield) sec, 
            COUNT(*) as 'Inserts'
    FROM MyTable
    GROUP BY    YEAR(datefield), 
                MONTH(datefield), 
                DAY(datefield), 
                DATEPART(hour, datefield), 
                DATEPART(minute, datefield), 
                DATEPART(second, datefield)

)

然后您可以从CTE中选择以获得每个时间单位的最大/最小/平均值。

如果您希望它更优雅,您可以在CTE上制作您可能想要的精细粒度(即毫秒或其他),然后您可以SELECT / { {1}}那个。

这样做的问题是GROUP BY并没有真正表现得那么好,因为它们基本上是没有索引或任何东西的一次性视图,因此在另一个查询中聚合CTE会很快陷入困境。

答案 2 :(得分:2)

扩展J Coopers的回答,我认为Rollup功能可能就是你所追求的。

SELECT      
    MAX([Insertions])                AS max_insertions,
    AVG([Average])                   AS avg_insertions,
     YEAR(orderdate),    AS YEAR
    MONTH(orderdate),   AS MONTH
    DAY(orderdate), AS DAY
    DATEPART(hour, orderdate), AS HOUR
    DATEPART(MINUTE, orderdate), AS MINUTE
    DATEPART(SECOND, orderdate) AS SECOND

FROM Sales.Orders
GROUP BY ROLLUP(
        YEAR(orderdate), 
        MONTH(orderdate), 
        DAY(orderdate), 
        DATEPART(hour, orderdate),
        DATEPART(MINUTE, orderdate),
        DATEPART(SECOND, orderdate)
    )