【发布时间】:2019-08-19 02:02:42
【问题描述】:
我有两个 SQL 表,Countries 和 CountryI18N:
Countries > Code
CountriesI18N > CountryCode, LanguageCode, Name
我得到一个选择以下国家的列表:
- 国家代码。
- 给定语言的国家名称I18N。
第一个 T-SQL 选项如下:
SELECT [x].[Code], (
SELECT TOP(1) [z].[Name]
FROM [CountriesI18N] AS [z]
WHERE ([z].[LanguageCode] = 'en' AND ([x].[Code] = [z].[CountryCode])
) AS [Name]
FROM [Countries] AS [x]
以及使用 Inner Join 的替代方法:
SELECT [x].[Code], [x.CountriesI18N].[Name]
FROM [Countries] AS [x]
INNER JOIN [CountriesI18N] ON [x].[Code] = [x.CountriesI18N].[CountryCode]
WHERE [x.CountriesI18N].[LanguageCode] = 'en'
它们在速度和效率方面是否相当?
如果我将有许多相关表,使用许多 InnerJoins 或子查询是否等效?
【问题讨论】:
-
打开 SSMS。按
<ctrl>+N。在新的查询窗口中,粘贴两个查询。按<ctrl>+M。运行查询。检查执行计划。 Race your horses. -
"子查询" = 子查询 :)
-
简短回答:
it depends。表大小、索引、碎片、数据类型,甚至表中的列数,它们都会产生影响。 一般如果你可以写成JOIN,你可能应该;优化器最熟悉这一点,人类更容易阅读和维护等等。但是哪个使用最多的资源,哪个更快(它们不是同一件事;单线程计划可以采取比多线程计划更长,但使用更少的资源)最好使用 SQL Server 的分析器和/或查看执行计划来衡量。 -
另外,您的查询也不相同。第一个保证每个代码一个名称。第二个允许每个代码有多个名称的可能性。他们可以产生不同的结果可能意味着他们产生不同的执行计划。更有理由检查执行计划以了解它们有多大不同,并使用分析器准确衡量资源的使用情况。
-
@MatBailie 如何更改第二个查询以仅获取一个名称?事实上,在 CountryLocalization 中,我对
有一个独特的约束,因为那是 PK。所以我知道对于每个 LanguageCode 我只会得到一个 Name。
标签: sql sql-server tsql sql-server-2014