【问题标题】:Optimizing SQL SERVER 2005 query优化 SQL SERVER 2005 查询
【发布时间】:2014-05-23 17:52:04
【问题描述】:

早上好,

我得到了 SQL 查询的这一部分:

WITH HC AS (
    SELECT Dia, Mes, Anyo, Hora, Energia AS HidroConv 
    FROM Calendar 
    LEFT OUTER JOIN OMP_PDBC_STOTA O 
        ON Calendar.Y = O.Anyo AND Calendar.M = O.Mes 
        AND Calendar.D = O.Dia AND Calendar.H = O.Hora 
    WHERE (Codigo = 1) AND Calendar.dt BETWEEN '12/31/2013' AND '01/01/2014')

SELECT Calendar.dt AS Fecha, Calendar.Y, Calendar.M, Calendar.D, Calendar.H, 
       HC.HidroConv
FROM Calendar 
LEFT OUTER JOIN HC 
     ON Calendar.Y = HC.Anyo AND Calendar.M = HC.Mes 
     AND Calendar.D = HC.Dia AND Calendar.H = HC.Hora 
WHERE dt BETWEEN '12/31/2013' AND '01/01/2014' 
ORDER by dt, h

在 WITH 部分,我还有 12 个查询。然后,在 SELECT 部分,我在 WITH 部分的每个 SELECT 中检索一列。在 FROM 部分,它们每个都有一个 LEFT OUTER JOIN,总是在连接的左侧有 Calendar。

这个大查询的执行时间超过 2 分钟,我迫切需要将时间缩短到 15 秒或更短。一些表,如 OMP_PDBC_STOTA 有 300 万行。

您对如何优化此查询有任何想法吗??

非常感谢您的帮助。

里卡多

【问题讨论】:

  • 首先简化查询 - 如果您要使用相同的字段对Calendar 进行十几个自连接,CTE 不会使其更容易、更快或更漂亮。然后应用适当的索引,至少在用于 JOIN 的字段上。我确信有一种更简单的方法可以实现您想要做的任何事情,但您没有提及您正在尝试做的是什么
  • 嗨帕纳吉奥蒂斯!我只需要获取:日期、年、月、日、小时,然后是来自同一个 OMP_PDBC_STOTA 的几个值的列表。我根据该表中的不同 Codigo 获取每个值。因此,对于 Codigo = 2,我还将获得来自 Energia 的另一个值。
  • 这是对您尝试编写的内容的描述,而不是您尝试执行的操作。您是否尝试按类别和小时对一组字段进行分组?那为什么不简单的加入呢?您是否尝试取消透视这些值,即将它们转换为行而不是列?
  • 是的,我正在尝试取消透视值,具体取决于每个人拥有的 Codigo,因此我将所有这些值与日期一起放在同一行。这些值都来自 OMP_PDBC_STOTA

标签: sql sql-server-2005


【解决方案1】:

这个查询是否给出相同的输出?

SELECT Calendar.dt AS Fecha, Calendar.Y, Calendar.M, Calendar.D, Calendar.H, Energia AS HidroConv
FROM Calendar 
    LEFT OUTER JOIN OMP_PDBC_STOTA O 
        ON Calendar.Y = O.Anyo AND Calendar.M = O.Mes 
        AND Calendar.D = O.Dia AND Calendar.H = O.Hora 
WHERE  
    Calendar.dt BETWEEN '12/31/2013' AND '01/01/2014' 
    AND Codigo = 1
ORDER by dt, h

如果是这样,它会更快,如果我错了告诉我,我会帮助你。

【讨论】:

  • 很难说,有时会变快有时不会。取决于我猜每个时刻数据库参与的查询数量。
  • 我在 OMP_PDBC_STOTA 上为 Anyo、Mes、Dia 和 Hora 字段创建了一个索引,查询从 15 秒变为 0 :D :D :D 非常感谢
  • 是的,子句条件连接字段的索引非常重要。很高兴它有帮助:)
【解决方案2】:

我发现我真的不需要日历来获得相同的结果。

你觉得这种做法怎么样?

SELECT  anyo, mes, dia, hora, Energia AS HidroConv
FROM OMP_PDBC_STOTA
WHERE  
    CAST(CAST(mes AS VARCHAR) + '/' + CAST(dia AS VARCHAR) + '/' + CAST(anyo AS VARCHAR) as datetime) BETWEEN '12/31/2013' AND '01/01/2014' 
    AND Codigo = 1
ORDER by mes,dia, hora

虽然找不到将 smallints (mes,dia,anyo) 转换为日期时间的正确方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多