我是SQL Server的新手。我最近获悉,执行的顺序是:
From
Where
Group By
Having
Select
Order By相关子查询和交叉应用是否符合执行顺序?
在select子句中,我有一个关联子查询的查询。不带where子句的外部查询返回10k行,应用where子句后返回50行。当外部查询有where子句时,关联子查询是执行10k次还是执行50次?
根据执行的逻辑顺序,它应该只执行50次,因为select语句是最后执行的语句之一。但是我的朋友说它执行了10k次,因为优化器在"From“逻辑执行顺序中执行这个命令。有什么想法吗?
发布于 2021-11-08 12:04:49
关系模型的一个新特性是将数据(表、查询)的逻辑表示与物理(磁盘文件、运行时执行)分离。您提供的列表是查询子句的逻辑序列。它不表示运行时引擎执行的物理顺序。
DBMS的一个组件称为查询优化器(QO)。它的工作是将所需输出(即SQL查询)的逻辑定义转换为一个合理有效的物理实现。它可以自由地将查询的部分重新排列成任何可证明等效的配置。
例如,如果查询具有QO的命令,则可能决定在执行结束时执行排序。或者,在开始时,它可以读取由于索引而已知的按期望顺序排列的数据。两个非常不同的物理实现,它们具有相同的逻辑结果。
物理实现的选择过程称为查询规划。这是一个深刻而引人入胜的话题。现在,大多数DBMS都使用基于成本的优化器。生成备选计划列表,根据内部专有成本函数对每个方案的成本进行评估,并为查询选择最便宜的方案。Server的优化器基于级联框架。网络上有很多解释它的资源。
要回答您的实际问题,逻辑上的子查询通常适合于SQL的任何部分。如果它们嵌入在FROM (..from T1 inner join (select x from t2) as y..)中,那么它们就被认为是FROM的一部分。如果在SELECT (select a, (select b from c where d='e') as f, g, h..)中,它们是SELECT的一部分。但是,在优化器认为最好这样做的任何地方,都会对它们进行评估。
“是执行10k次或50次的相关子查询”--可能是其中的一个,也可能没有。它可以执行一次,并在运行时缓存。它将取决于精确的SQL、表定义、每个表中涉及的行数、在编译时和运行时设置了哪些选项。如果你想要一个完整的解释,问一个新的问题,其中包括所有表,索引和约束的定义。将实际执行计划复制到https://www.brentozar.com/pastetheplan/。DBA.SE上有很多常客可以解释这意味着什么。
子查询确实带来了额外的优化挑战。有一篇由Mostafa等人撰写的题为“Subqueries的执行策略”的论文,我发现它既有趣又可读性强。
https://dba.stackexchange.com/questions/302202
复制相似问题