首页 > 解决方案 > 为按日期和小时过滤的查询优化表?

问题描述

我们有一个存储每小时数据的历史表。目前,该表有 8000 万行,并且只有今年的 YTD 数据。导入完成后,数据以这种格式存储。

表架构如下所示:

CREATE TABLE [dbo].[ElectricFaults](
    [ElectricFaultsId] [int] IDENTITY(1,1) NOT NULL,
    [DateTimeDt] [smalldatetime] NULL,
    [Street] [varchar](5) NULL,
    [StreetSector] [varchar](25) NULL,
    [FaultValue] [smallint] NULL,
    [InsertDate] [datetime] NULL
)

该表有两个非聚集索引:一个带有ElectricFaultsId,另一个带有DateTimeDt。我还没有添加主键。

我将按月分组,分组将由该查询中的数据确定:

select *
From 
ElectricFaults pm inner join DimStreetSectors dim on
RIGHT(StreetSector, LEN(StreetSector)-5) = dim.StreetSector
where 
pm.DateTimeDt >= dim.AddedDate
and cast(pm.[datetimedt] as date) between '2019-01-01' and '2019-11-25'
and ((datepart(hh, pm.datetimedt) between 20 and 23) or (datepart(hh, pm.datetimedt) between 0 and 4))
and FaultValue>= 30 --30 mins

目前,结果显示在 14-15 秒内,并返回 54K 行。

我会怎么做来优化这个查询?没有它,inner join它需要一分钟才能完全执行并返回超过 1M 行。

我正在考虑RIGHT通过添加一个包含RIGHT(StreetSector, LEN(StreetSector)-5). 我也在考虑包含一个hour列,因为我通过它过滤。

标签: sql-servertsqlsql-server-2008

解决方案


您可以尝试在表 [dbo].[ElectricFaults] 上为 RIGHT(StreetSector, LEN(StreetSector)-5) 创建一个计算列。

(您可以阅读有关计算列的一些注意事项 - http://www.sqlservice.se/sql-server-performance-death-by-computed-column/


推荐阅读