这些有什么区别?

时间:2012-10-08 15:32:29

标签: sql sql-server sql-server-2008 tsql

两个查询之间有什么区别?

   SELECT     CountryMaster.Id
   FROM       Districts INNER JOIN
   CountryMaster ON Districts.CountryId = CountryMaster.Id

   SELECT     CountryMaster.Id
   FROM       CountryMaster INNER JOIN
   Districts ON Districts.CountryId = CountryMaster.Id  

我知道输出会是相同的,但我想要知道,如果我忽略复杂查询中的表和列的位置或者有数十万行数据的表格,那么是否存在相同的重大影响。

2 个答案:

答案 0 :(得分:8)

无论如何都没有区别。连接的顺序无关紧要。数据库引擎内的查询优化器将决定合并计划,以根据这些表中数据的存储统计信息实际处理两个表中的记录。
实际上,在许多情况下,查询优化器将为使用连接的查询生成完全相同的计划,就像使用相关子查询表达的查询一样。 我所学到的教训是:

始终以最清楚地表示您尝试创建的流程的含义的语法或表示开始,并信任查询优化器来完成其工作。话虽如此,查询优化器并不完美,所以如果存在性能问题,请使用查询show plan with alternate constructions,看看它是否有所改进......

快速评论内部和外部联接的表现。内部连接本质上比外部连接更快是不正确的。相对性能完全取决于查询引擎使用三种类型的处理连接中的哪一种;
    1.嵌套循环加入,2.,合并加入,或3.哈希加入。
例如,当连接一侧的记录集远小于另一侧的记录集时,使用嵌套循环连接,并且在连接列[s]上索引较大的集合。在这种情况下,如果较小的集合是“外部”侧,则外部连接将更快。原因是嵌套循环连接从该较小的集合中获取整个记录集,并遍历每个记录,从匹配的较大集合中查找记录。当较大的集合中没有找到匹配时,内部联接必须执行从较小的一侧移除行的第二步。外连接不会执行此第二步。

三种可能类型的连接过程中的每一种都有自己的特征行为模式......有关详细信息,请参阅Nested Loop JoinsMerge JoinsHash Joins

答案 1 :(得分:1)

如上所述,它们完全相同。 Charles的优秀答案。

如果您想知道他们是否会有不同的执行计划,那么只需在SSMS中显示执行计划。

至于速度是否已将索引中使用的列编入索引 维护索引 - 碎片指数几乎没有那么有效 查询计划并不总是一样的 查询优化器保留统计信息,并且作为数据更改的配置文件,最佳计划可能会发生变化 成千上万的行不是很多 一旦你进入数百万,然后调整索引和语法(提示) 有些时候,在有足够的数据进行调整之前,你必须要花费数百万。

还有一个等效且有时更快的UNION运算符。

连接提示循环不是对称的,因此在这种情况下,查询计划对于以下内容是不同的,但它们仍然是相同的结果。

如果一个是PK表,我总是把它放在第一位 在这种情况下,第一个是第二个的两倍。

select top 10 docSVsys.sID, docMVtext.fieldID
from docSVsys 
inner loop join docMVtext 
   on docMVtext.sID = docSVsys.sID
where docSVsys.sID < 100
order by docSVsys.sID, docMVtext.fieldID

select top 10 docSVsys.sID, docMVtext.fieldID
from docMVtext
inner loop join docSVsys 
   on docMVtext.sID = docSVsys.sID
where docSVsys.sID < 100
order by docSVsys.sID, docMVtext.fieldID

Advanced Query Tuning Concepts