为啥有些列会减慢查询速度

Posted

技术标签:

【中文标题】为啥有些列会减慢查询速度【英文标题】:why do some columns slow down the query为什么有些列会减慢查询速度 【发布时间】:2013-01-22 23:27:16 【问题描述】:

我使用的是 SQL Server 2012。

我正在尝试优化这样的查询:

SELECT TOP 20 ta.id, 
              ta.name, 
              ta.amt, 
              tb.id, 
              tb.name, 
              tc.name, 
              tc.id, 
              tc.descr 
FROM   a ta 
       INNER JOIN b tb 
               ON ta.id = tb.id 
       INNER JOIN c tc 
               ON tb.id = tc.id 
ORDER  BY ta.mytime DESC 

查询运行大约需要 5 - 6 秒。连接中使用的所有列都有索引。这些表有 500k 条记录。

我的问题是:当我从选择中删除列 tc.name、tc.id 和 tc.descr 时,查询会在不到一秒的时间内返回结果。为什么?

【问题讨论】:

因为您要从 JOIN 中删除整个表。您应该从最大的表开始,然后 JOIN 到较小的表。 c 经常被写信吗? 如果您使用的是 SQL Management Studio,您可以运行优化器来查看执行计划。这可能会提供一些关于问题到底是什么的见解:simple-talk.com/sql/sql-training/the-sql-server-query-optimizer 您需要向我们展示表和索引定义。 诊断慢查询需要完整的表和索引定义,而不仅仅是描述或解释。也许您的表格定义不佳。也许索引没有正确创建。也许您认为您在该列上没有索引。没有看到表和索引定义,我们无法判断。如果您知道如何处理EXPLAIN,请将结果也放入问题中。 【参考方案1】:

您需要发布执行计划才能真正了解其中的区别。

据我所知,SQL Server优化连接。毕竟,即使选择列表中没有列,连接仍然可以用于过滤和相乘行数。

但是,可能会跳过一个步骤。使用select 中的变量,引擎需要同时访问索引 获取包含数据的页面。如果没有变量,引擎就不需要进行提取。这可能会巧妙地将优化器的平衡从一种连接类型转变为另一种连接类型。

第二种可能性只是涉及时间。如果您运行一次查询,则可能会在机器上填充页面缓存。第二次运行它时,查询速度要快得多,因为数据在内存中。永远不要运行计时,除非您 (1) 在每次调用之间清除缓存或 (2) 确保缓存已被等效填充。

【讨论】:

【参考方案2】:

您有聚集索引吗?如果没有,您应该创建聚集索引并运行查询整数,并且主要在主键列上运行。

检查 http://msdn.microsoft.com/en-us/library/aa933131(v=sql.80).aspx 是否有聚集索引。

【讨论】:

【参考方案3】:

我终于能够通过向表中添加额外的索引来调整查询。 SQL Server 没有显示/暗示缺少索引,但我通过在选择中存在的字段上创建新的非聚集索引来解决这个问题。

感谢大家的帮助。

@Wade 这个链接对理解 SQL 优化器很有帮助

【讨论】:

以上是关于为啥有些列会减慢查询速度的主要内容,如果未能解决你的问题,请参考以下文章

为啥没有聚合的结束 Group By 会减慢我的查询速度?

MongoDB,即使它们形成分区,查询字段也会减慢查询速度吗?

oracle中加索引会不会加快更新的速度?有人说会减慢更新速度?谁知道为啥吗?

为啥NATIVE FOR ORACLE查询速度慢

如何减慢postgresql服务器的速度?

在某些情况下,为什么CTE(公用表表达式)与SQL Server中的临时表相比会减慢查询速度