小表上的简单 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 的计算机上执行。表Documents
和Companies
的记录数只有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 查询执行时间过长的主要内容,如果未能解决你的问题,请参考以下文章