需要帮助优化 SQL 查询

Posted

技术标签:

【中文标题】需要帮助优化 SQL 查询【英文标题】:Need Help Optimizing SQL query 【发布时间】:2016-06-21 15:01:52 【问题描述】:

首先我想说我对 SQL 还很陌生,所以这似乎是一个愚蠢的问题。 因此,在这段代码中,我收到一个日期作为参数,向其添加 61 分钟并检查其间的值。 然后我对每一列的值求和并将其存储在另一个表中。 代码工作得很好,我想知道是否有更好的方法和方法。(不使用这么多行或重复的代码)

提前致谢。

alter procedure Contagem
@date datetime

as
begin
    declare
    @Sala1 float,
    @Sala2 float,
    @Sala3 float,
    ...
    @Sala26 float,
    @Sala27 float,
    @Sala28 float,
    @dateplus datetime

    set @Teste = 1
    set @dateplus =  (select DATEADD(MINUTE,61,@date))

    set @Sala1 =  (select sum(Sala_1_Energia) from Energia_15min where Time_Stamp between @date and @dateplus)
    set @Sala2 =  (select sum(Sala_2_Energia) from Energia_15min where Time_Stamp between @date and @dateplus)
    set @Sala3 =  (select sum(Sala_3_Energia) from Energia_15min where Time_Stamp between @date and @dateplus)
    ...
    set @Sala26 =  (select sum(Sala_26_Energia) from Energia_15min where Time_Stamp between @date and @dateplus)
    set @Sala27 =  (select sum(Sala_27_Energia) from Energia_15min where Time_Stamp between @date and @dateplus)
    set @Sala28 =  (select sum(Sala_28_Energia) from Energia_15min where Time_Stamp between @date and @dateplus)

    Insert into Custos_hora values (@date,@Sala1,@Sala2,@Sala3,@Sala4,@Sala5,@Sala6,@Sala7,@Sala8,@Sala9,@Sala10,@Sala11,@Sala12,@Sala13,@Sala14,@Sala15,@Sala16,@Sala17,@Sala18,@Sala19,@Sala20,@Sala21,@Sala22,@Sala23,@Sala24,@Sala25,@Sala26,@Sala27,@Sala28)
end

【问题讨论】:

你真的需要阅读规范化。你有重复的列,这使得事情很难处理。您当然可以通过在单个 select 语句中设置所有变量而不是一遍又一遍地访问同一个表来使其性能更好。但实际上最好的选择是将该表完全重构为规范化的表结构。 @Dumbrica:到目前为止,您得到的最佳答案是我认为 Sean Lange 的评论。 这里的另一个问题是您在浮点数上使用 SUM。这表明您希望这些值具有某种精度。 float 数据类型是近似数据类型,不能保存所有值。如果你想要准确,你应该考虑改用十进制或数字。 @SeanLange 好的,谢谢,我会仔细阅读。至于变量将数据类型更改为十进制。 【参考方案1】:

您可以只打那张桌子一次,而不是像现在这样打 28 次。

INSERT INTO Custos_hora
SELECT
SUM(Sala_1_Energia)
,SUM(Sala_2_Energia)
,SUM(Sala_3_Energia)
,SUM(Sala_4_Energia)

FROM Energia_15min

WHERE Time_Stamp between @date and @dateplus

最好这样声明要插入的字段;

INSERT INTO Custos_hora (Field1, Field2, Field3, Field4)
SELECT
SUM(Sala_1_Energia)
,SUM(Sala_2_Energia)
,SUM(Sala_3_Energia)
,SUM(Sala_4_Energia)

FROM Energia_15min

WHERE Time_Stamp between @date and @dateplus

另外,变量@Teste 是干什么用的?它似乎没有在任何地方使用。而且您似乎也没有声明@date

【讨论】:

忽略@teste,我之前用它来测试一些东西,忘记删除了。 是的,我相信我们都曾使用过测试代码 :) 如果这些答案中的任何一个有帮助,请随时为它们投票。此外,如果您可以将其中一个标记为已接受的答案,我们将不胜感激。【参考方案2】:

您可以改为执行以下操作:

Alter Procedure Contagem (@Date DateTime)
As Begin
    Insert  Custos_hora
    Select  @Date,
            Sum(Sala_1_Energia),
            Sum(Sala_2_Energia),
            Sum(Sala_3_Energia),
            Sum(Sala_4_Energia),
            Sum(Sala_5_Energia),
            Sum(Sala_6_Energia),
            Sum(Sala_7_Energia),
            Sum(Sala_8_Energia),
            Sum(Sala_9_Energia),
            Sum(Sala_10_Energia),
            Sum(Sala_11_Energia),
            Sum(Sala_12_Energia),
            Sum(Sala_13_Energia),
            Sum(Sala_14_Energia),
            Sum(Sala_15_Energia),
            Sum(Sala_16_Energia),
            Sum(Sala_17_Energia),
            Sum(Sala_18_Energia),
            Sum(Sala_19_Energia),
            Sum(Sala_20_Energia),
            Sum(Sala_21_Energia),
            Sum(Sala_22_Energia),
            Sum(Sala_23_Energia),
            Sum(Sala_24_Energia),
            Sum(Sala_25_Energia),
            Sum(Sala_26_Energia),
            Sum(Sala_27_Energia),
            Sum(Sala_28_Energia)
    From    Energia_15min
    Where   Time_Stamp Between @Date And DateAdd(Minute, 61, @Date)
End

【讨论】:

【参考方案3】:

多次SELECT语句会进行多次表扫描,增加磁盘IO和内存利用率。它可以在单个选择语句中完成。

    alter procedure Contagem
      @date datetime

      as
      begin


      declare
      @Sala1 float,
      @Sala2 float,
      @Sala3 float,
      @Sala4 float,
      @Sala5 float,
      @Sala6 float,
      @Sala7 float,
      @Sala8 float,
      @Sala9 float,
      @Sala10 float,
      @Sala11 float,
      @Sala12 float,
      @Sala13 float,
      @Sala14 float,
      @Sala15 float,
      @Sala16 float,
      @Sala17 float,
      @Sala18 float,
      @Sala19 float,
      @Sala20 float,
      @Sala21 float,
      @Sala22 float,
      @Sala23 float,
      @Sala24 float,
      @Sala25 float,
      @Sala26 float,
      @Sala27 float,
      @Sala28 float,
      @dateplus datetime

     set @Teste = 1
     set @dateplus =DATEADD(MINUTE,61,@date))

    Insert into Custos_hora
      select sum(Sala_1_Energia),
      sum(Sala_2_Energia),
      sum(Sala_3_Energia),
      sum(Sala_4_Energia),
      sum(Sala_5_Energia),
      sum(Sala_6_Energia),
      sum(Sala_7_Energia),
      sum(Sala_8_Energia),
      sum(Sala_9_Energia),
      sum(Sala_10_Energia),
      sum(Sala_11_Energia),
      sum(Sala_12_Energia),
      sum(Sala_13_Energia),
      sum(Sala_14_Energia),
      sum(Sala_15_Energia),
      sum(Sala_16_Energia),
      sum(Sala_17_Energia),
      sum(Sala_18_Energia),
      sum(Sala_19_Energia),
      sum(Sala_20_Energia),
      sum(Sala_21_Energia),
      sum(Sala_22_Energia),
      sum(Sala_23_Energia),
      sum(Sala_24_Energia),
      sum(Sala_25_Energia),
      sum(Sala_26_Energia),
      sum(Sala_27_Energia),
      sum(Sala_28_Energia) from Energia_15min where Time_Stamp between @date and @dateplus
      end 

【讨论】:

以上是关于需要帮助优化 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

需要帮助优化 T-SQL 查询

需要帮助来优化 ORACLE SQL 查询 [关闭]

需要帮助优化外连接 SQL 查询

需要帮助优化 SQL Server 查询

需要帮助优化涉及数百万条记录的非常慢的 DB2 SQL 查询

请帮助优化查询