小表上的简单 SQL 查询执行时间过长

Posted

技术标签:

【中文标题】小表上的简单 SQL 查询执行时间过长【英文标题】:Simple SQL query on small tables takes too long to execute 【发布时间】:2015-10-07 18:16:48 【问题描述】:

我有一个查询需要很长时间才能执行。它很简单,桌子很小。简化的查询(但仍然很慢)是:

SELECT D.ID, C.Name, T.Name AS TownName
  FROM Documents D, Companies C, Towns T
  WHERE C.ID = D.Company AND T.ID = C.Town
  ORDER BY C.Name

表之间的主键和外键设置正确。此外,列 Companies.Name 已编入索引。

我尝试使用 JOIN、重新启动 SQL Server、重建索引等,但它仍然需要大约 40 秒才能在我的带有 SSD 的计算机上执行。表DocumentsCompanies的记录数只有18K(目前是1:1),表Towns只有大约20条记录。

另一方面,以下查询返回完全相同的记录,但执行起来几乎没有时间:

SELECT D.ID, C.Name, (SELECT Name FROM Towns WHERE ID = C.Town) AS TownName
  FROM Documents D, Companies C
  WHERE C.ID = D.Company
  ORDER BY C.Name

在我看来,第一次查询应该更快,但我显然错了。有人知道这里发生了什么吗?在表中按列排序时,索引似乎被忽略了,该表是一个主表,另一个表的详细信息。

【问题讨论】:

你为什么还在使用旧的 ANSI-89 样式连接?您应该使用较新的连接语法,它已经存在 20 多年了。 sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/… 如果你去 Town > Company > Documents.. 使用连接会发生什么 如果您需要真正的帮助,您需要提供实际的 ddl,包括索引定义以及表的行数。一个实际的执行计划也会有所帮助。 你看过计划了吗?它应该告诉你资源被用在了哪里。 【参考方案1】:

我无法解释为什么您的子查询运行得更快,但我会尝试其他方法,看看是否可以消除子查询。

当我不使用 where 条件时,我通常从最小到最大。所以我的查询看起来像

Select  t.Name TownName,
        c.Name,
        d.Id
From    Towns t
        Join Companies c ON t.Id = c.Town
        Join Documents d ON c.Id = d.Company
Order By c.Name

然后我会确保 Companies 有一个关于 Town 的索引,并且 Documents 有一个关于 Company 的索引。18k 记录可能需要一段时间才能显示在输出窗口中,但查询应该很快

【讨论】:

查询同样慢。此外,在 Town 上添加索引没有帮助,但在 Documents 表中的 Company 上添加索引有效!我(错误地)认为外键就足够了。尽管如此,尽管它是不同的表,但为什么其他查询运行良好,这对我来说仍然是一个谜。此外,从查询中删除 Cities 表将使查询变得即时。【参考方案2】:

使用 join 语句会发生什么?

SELECT D.ID, C.Name, T.Name AS TownName
FROM Documents D
inner join Companies C on C.
inner join Towns T on T.ID = C.Town
ORDER BY C.Name

还有,试试有无订单

【讨论】:

正如我所提到的,我尝试过这样的 INNER JOINS,它同样慢:SELECT D.ID, C.Name, T.Name AS TownName FROM Companies C INNER JOIN Documents D ON C.ID = D.Company INNER JOIN Towns T ON T.ID = C.Town ORDER BY C.Name 我也尝试在WHERE 中使用Documents 表,正如你所建议的,但没有任何改变。没有ORDER,它是即时的。

以上是关于小表上的简单 SQL 查询执行时间过长的主要内容,如果未能解决你的问题,请参考以下文章

内部连接的 SQL 查询执行时间慢

同一张表上的多个连接,在一个查询中计数

小表上的仅索引扫描非常慢

SQL 查询执行时间过长。需要提高查询的性能

MySQL innoDB:查询执行时间过长

sqlserver查询执行时间过长的sql