【问题标题】:SQL Query taking foreverSQL 查询永远存在
【发布时间】:2010-01-27 13:40:40
【问题描述】:

我有这个网络应用程序工具,它​​可以查询数据并将其显示在网格中。现在很多人都在使用它,所以它必须非常高效。

问题是,我需要通过连接添加几个额外的字段,现在查询运行需要很长时间。

如果我在 sql server 中运行以下查询:

select top 100 *
from bam_Prestatie_AllInstances p
join bam_Zending_AllRelationships r on p.ActivityID = r.ReferenceData
join bam_Zending_AllInstances z on r.ActivityID = z.ActivityID
where p.PrestatieZendingOntvangen >= '2010-01-26' and p.PrestatieZendingOntvangen < '2010-01-27'

这大约需要 35-55 秒,这太长了。因为这只是一小部分。

如果我删除两个日期检查之一,它只需要 1 秒。如果我删除这两个连接也只需要 1 秒。

当我对此使用查询计划时,我可以看到 100% 的时间都花在了 PrestatieZendingOntvangen 字段的索引上。如果我将此字段设置为索引,则不会发生任何变化。

有人知道该怎么做吗?

因为我的客户开始抱怨超时等问题。

谢谢

【问题讨论】:

  • 请张贴表格架构
  • 在 ... 和 ... 之间使用运算符来表示两个日期
  • 如果您不在WHERE 子句中使用它们,为什么还要使用它们?
  • 因为我需要来自其他数据库的数据,并且需要将它们转换为 c# 中的列表。但显然,如果我在我的 z 数据上执行 where's 会更快,所以你所说的有些道理

标签: sql-server datetime join


【解决方案1】:

除了bam_Prestatie_AllInstances.PrestatieZendingOntvangen 列上的索引的明显问题外,还要检查您是否有外键列的索引:

  • p.ActivityID(表:bam_Prestatie_AllInstances
  • r.ReferenceData(表:bam_Zending_AllRelationships
  • r.ActivityID(表:bam_Zending_AllRelationships
  • z.ActivityID(表:bam_Zending_AllInstance

索引外键字段可以帮助加快这些字段的连接速度!

另外,正如已经提到的:尝试通过指定特定的字段列表来限制您选择的字段 - 而不是使用 SELECT * - 特别是如果您加入多个表格,只是您选择的列数(乘以根据您选择的行数)可能会导致大量数据传输 - 如果您不需要所有这些列,那只是浪费带宽!

【讨论】:

  • 我已经做了所有这些,这是标准的。而且我还选择了字段,这只是为了使查询更具可读性。我发现的主要问题是,如果我删除前 100 名,它会快很多,我认为当我使用前 100 名时它会将其复制到临时数据库。我显然不能全部使用它们,因为这会使我们的网络超载.
【解决方案2】:
  1. 指定要检索的字段,而不是 *
  2. 指定内连接或外连接

【讨论】:

    【解决方案3】:

    尝试一下?

    where p.PrestatieZendingOntvangen 
       between '2010-01-26 00:00:00' and '2010-01-27 23:00:00'
    

    【讨论】:

    • 这只是语法糖 - 底层查询计划将是相同的,所以恐怕真的没有帮助。
    • 加上可能会返回不同的结果。 BETWEEN 包含在内,而且您已声明 23:00....
    【解决方案4】:

    您是否在Where 子句中的日期字段上放置了索引

    如果没有,我会在该字段上创建一个索引,看看它是否对您的时间有任何影响。

    当然,索引会占用更多磁盘空间,因此您必须考虑额外索引的影响。

    编辑:

    其他人也提出了很好的观点,即在 Select 而不是 *(通配符)中指定您需要哪些列,以及在外键上放置更多索引等。

    【讨论】:

    • 啊,好吧...在完整阅读问题之前,我先开枪了!
    【解决方案5】:

    有数据库背景的人可以解决我对此的疑问。

    我认为,您应该以数据库能够理解的样式指定日期。
    例如假设日期以 mm/dd/yyyy 样式存储在表中,并且您的查询尝试放入不同样式的日期进行比较 (yyyy-mm-dd),性能将会下降。

    当我假设这一点时,我是不是太天真了?

    【讨论】:

    • 不,事实并非如此。日期存储为 DATETIME - 而不是特定格式的字符串。您指定的字符串将被转换为 DATETIME,并进行比较。
    • @marc_s:是的,我同意。但是,当进行比较时,不会对每一行进行转换吗?感谢您的回复。
    • 我希望不会!我相信 SQL Server 的查询优化器会足够聪明,可以将这两个边界值转换一次,然后为每一行重用它们。
    【解决方案6】:

    bam_Prestatie_AllInstances 和其他表有多少列?看起来您正在删除所有列,这肯定是一个性能问题。

    您是否尝试过从特定表格中选择特定列,例如:

    select top 100 p.column1, p.column2, p.column3
    

    而不是像您当前那样查询所有列:

    select top 100 *
    

    【讨论】:

      猜你喜欢
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多