我有一个查询,它在一个月的每个小时中获取每天的所有数据,而当我在sql server中运行它时,花费的时间太多了,我的Web报告中出现了超时错误。还有其他方法可以查询并获得相同的结果吗?
SELECT DISTINCT CONCAT(date,' ',FORMAT(CAST([dbo].[TALAGA_PL70_FEEDER_1].time as datetime) , 'HH')) as Time,
[dbo].[TALAGA_PL70_FEEDER_1].Ia,
[dbo].[TALAGA_PL70_FEEDER_1].Ib,
[dbo].[TALAGA_PL70_FEEDER_1].Ic,
[dbo].[TALAGA_PL70_FEEDER_1].Ineutral
FROM [dbo].[TALAGA_PL70_FEEDER_1]
JOIN (
SELECT CONCAT(date,' ',MIN(time)) as mints FROM [TALAGA_PL70_FEEDER_1]
WHERE (date >= '2019-04-26'
AND date <= '2019-05-25')
GROUP BY date, DATEPART(hh, time)
)tt
ON [dbo].[TALAGA_PL70_FEEDER_1].time = tt.mints AND [TALAGA_PL70_FEEDER_1].date = tt.mints
ORDER BY 1 ASC
以下是示例SQL结果:
Time | Ia | Ib | Ic | Ineutral
-------------------------------------------------------------------------------------------
2019-04-26 00 | 169.809661865234 | 163.836029052734 | 157.159591674805 | 13.2650079727173
2019-04-26 01 | 159.619323730469 | 155.754028320313 | 149.516830444336 | 10.7174234390259
2019-04-26 02 | 152.855056762695 | 148.814056396484 | 140.819900512695 | 12.0351390838623
2019-04-26 03 | 146.969253540039 | 144.773056030273 | 135.900436401367 | 11.1566619873047
表架构:
GO
CREATE TABLE [dbo].[TALAGA_PL70_FEEDER_1](
[id] [int] IDENTITY(1,1) NOT NULL,
[date] [date] NOT NULL,
[time] [time](7) NOT NULL,
[Ineutral] [float] NULL,
[Ia] [float] NULL,
[Ib] [float] NULL,
[Ic] [float] NULL,
[Iave] [float] NULL,
[Ig] [float] NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[TALAGA_PL70_FEEDER_1] ADD CONSTRAINT
[DF__TALAGA_FEE__date__0F975522] DEFAULT (getdate()) FOR [date]
GO
ALTER TABLE [dbo].[TALAGA_PL70_FEEDER_1] ADD CONSTRAINT
[DF__TALAGA_FEE__time__108B795B] DEFAULT (getdate()) FOR [time]
我在网络报告中遇到的错误:
Array([0] => Array([0] => 08S01 [SQLSTATE] => 08S01 [1] => 258 [code] => 258 [2] => [Microsoft] [ODBC Driver for SQL服务器]共享内存提供程序:超时错误[258]。[消息] => [Microsoft] [SQL Server的ODBC驱动程序11:超时错误[258]。] [1] =>数组([0] = > 08S01 [SQLSTATE] => 08S01 [1] => 258 [代码] => 258 [2] => [Microsoft] [用于SQL Server的ODBC驱动程序11]通信链接失败[消息] => [Microsoft] [ODBC驱动程序11 for SQL Server]通信链接失败)[2] =>数组([0] => 08S01 [SQLSTATE] => 08S01 [1] => -2147467259 [code] => -2147467259 [2] => [Microsoft] [用于SQL Server的ODBC驱动程序11]通信链接失败[消息] => [Microsoft] [用于SQL Server的ODBC驱动程序11]通信链接失败))
答案 0 :(得分:1)
除非您没有将其包括在内,否则您的表似乎没有索引。我还假设查询查询的月份比数据更多。因此查询每次都必须查看整个表。实际上,它可能两次击中整个表,一次是在内部查询中创建每小时的时段,然后再次确定是将每一行放入哪个时段。
您可能对如何正确建立索引有不同意见,但是如果这是我的数据库,我会在id列上创建一个主聚集索引,然后在日期(包括时间列)上创建一个非聚集索引。
您可能还需要在外部查询中添加where子句,以将其过滤为与内部查询相同的日期范围。
答案 1 :(得分:0)
尝试使用窗口功能:
SELECT date,
RIGHT('00' + DATENAME(hour, f.time), 2) as Time,
f.Ia, f.Ib, f.Ic, f.Ineutral
FROM (SELECT f.*,
ROW_NUMBER() OVER (PARTITION BY date, DATEPART(HOUR, f.time) ORDER BY f.time ASC) as seqnum
FROM [dbo].[TALAGA_PL70_FEEDER_1] f
WHERE date >= '2019-04-26' AND
date <= '2019-05-25'
) f
WHERE seqnum = 1;
ORDER BY 1 ASC;
注意:
FORMAT()
据说比其他日期/时间功能要慢得多,但我怀疑这会对您的时间安排产生很大影响。date
上创建一个索引。ROW_NUMBER()
进行任何操作。