我能否 100% 依靠逻辑处理来了解在后续查询子句中哪些对象(列、别名、表等)“可用”?

can I rely 100% on logical processing to know which objects (columns aliases, tables, etc) I have "available" in subsequent query clauses?

提问人:jwa 提问时间:11/14/2023 最后编辑:jwa 更新时间:11/15/2023 访问量:128

问:

文档说逻辑处理用于知道我可用于查询的下一个子句的内容,但后来它自相矛盾地说顺序可以改变,这让我感到困惑。

这里是逻辑处理

SELECT 语句的逻辑处理顺序

以下步骤显示了逻辑处理顺序或绑定 order,用于 SELECT 语句。此顺序决定了对象何时 在一个步骤中定义的子句可用于后续的子句 步骤。例如,如果查询处理器可以绑定到(访问) 在 FROM 子句中定义的表或视图、这些对象及其 列可用于所有后续步骤。相反 因为 SELECT 子句是步骤 8,所以任何列别名或派生 该子句中定义的列不能由前面的引用 第。但是,它们可以被后续子句引用,例如 ORDER BY 子句。语句的实际物理执行是 由查询处理器确定,顺序可能与此不同 列表。

1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. WITH CUBE or WITH ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP

警告

前面的序列通常为 true。然而,有不常见的 顺序可能不同的情况。

例如,假设您在视图上有一个聚集索引,并且 view 排除某些表行,视图的 SELECT 列列表使用 将数据类型从 varchar 更改为整数的 CONVERT。在这个 情况下,CONVERT 可能会在 WHERE 子句执行之前执行。 确实不常见。通常有一种方法可以修改视图以避免 不同的顺序,如果它对你的情况很重要。

  1. 这是否意味着,例如,有时子句先于子句执行,有时子句先执行,后子句?WHEREFROMFROMWHERE
  2. 我能否 100% 依靠逻辑处理来知道哪些对象(列、别名、表等)在后续查询子句中“可用”?

我还从一位 SQL 的 StackOverflow 专家那里读到了这篇文章:

顺便说一句,SQL是一种描述性语言,而不是过程语言。查询不指定“执行顺序”。这是确定的 由编译器和优化器提供。你所指的是“订单 的解析“,它解释了如何在查询中解析标识符。

  1. 那么,如果物理处理(数据库、优化器、索引等)决定了查询的执行顺序,那么逻辑处理的意义何在?
  2. 这是否意味着物理处理可以“跳过”(更改、修改,我不知道正确的词是什么)逻辑处理步骤?
  3. 执行逻辑处理,然后执行物理处理?,还是如何执行?
mysql sql-server

评论

0赞 GuidoG 11/14/2023
也许你可以问这个问题 dba.stackexchange.com
2赞 siggemannen 11/14/2023
我认为你想多了。只要查询的“最终结果”与您的语句匹配,SQL Server 就可以执行任何操作。它甚至可能将内容放入 nosql 数据库中,然后将 sql 重写为另一种语法,然后返回结果。但是,作为开发人员,您可以编写适当的查询,即。不要跳到前面并在 WHERE 中使用 SELECT 别名(这是不允许的)。逻辑处理将您希望看到的最终结果固定下来,而物理部件有望在尽可能短的时间内提供此结果
0赞 jwa 11/14/2023
"逻辑处理是你希望看到的最终结果的一成不变的“——那么,为什么它说一个子句在某些情况下可能先于另一个子句,有时甚至出现在另一个子句之后呢?@siggemannen
0赞 siggemannen 11/15/2023
因为预期结果 != 执行。执行不是一成不变的
0赞 siggemannen 11/15/2023
一个愚蠢的例子。你是画家。有人告诉你把房子涂成白色。但是这个人不在乎你是用刷子、机器还是指甲油,只要你做得越白越好越好。他也不在乎你是从客厅、浴室开始,还是每个房间做几个小时

答:

2赞 GSerg 11/15/2023 #1
  1. 这是否意味着,例如,有时子句先于子句执行,有时子句先执行,后子句?WHEREFROMFROMWHERE

不,因为为了过滤某些东西(WHERE),你需要知道你正在过滤什么(FROM)。因此,某种 FROM 肯定会在某种 WHERE 之前发生。
我之所以说“某种排序”,是因为实际发生的确切 FROM 可能不是您在查询中指定的确切 FROM。这不仅包括 FROMed 对象的顺序,甚至包括它们的组成(RDBMS 可以用等效对象(表/视图)替换对象,或者在不影响最终结果的情况下完全省略 FROMing 对象)。

  1. 我能否 100% 依靠逻辑处理来知道哪些对象(列、别名、表等)在后续查询子句中“可用”?

不,您依赖于 SQL 语法。可用的别名取决于查询的每个文本点的嵌套级别。

  1. 那么,如果物理处理(数据库、优化器、索引等)决定了查询的执行顺序,那么逻辑处理的意义何在?

逻辑处理的重点是建立需要实现的正确结果。完成此操作后,您可以想出一种完全不同的方法来实际实现该结果,即以非常意想不到的方式访问和处理数据。

  1. 这是否意味着物理处理可以“跳过”(更改、修改,我不知道正确的词是什么)逻辑处理步骤?

物理处理只关注生成逻辑处理本来会产生的结果。它丝毫不关心保留任何类型的操作顺序,只要最终结果与逻辑处理所达到的结果相同。请参阅“假设”规则到底是什么?

  1. 是先执行逻辑处理,然后执行物理处理?,还是如何执行?

这是一个哲学问题。
你可能会说是这样,因为查询优化器的编写方式使其结果与逻辑处理的结果相匹配,因此从这个意义上说,逻辑处理是“首先执行的”(因为它影响了优化器从步骤 1 开始的决策)。
或者你可以说根本没有执行逻辑处理。

评论

0赞 Charlieface 11/15/2023
答案 1 混淆了物理和逻辑。第 2 点说“不,你依赖于 SQL 语法”,但逻辑处理本质上是语法,即它是该语法的逻辑结果。应该注意的是,运行时错误(例如div为零)可以超越逻辑处理(在范围之间移动),因此对于此类错误,物理结果有时与逻辑结果不同。
0赞 GSerg 11/15/2023
@Charlieface第 1 点只是关于物理的,尽管在决定要过滤什么之前,无论是物理上还是逻辑上,您都无法过滤某些东西。第 2 点,我不认为逻辑处理是语法,尤其是在狭义的别名可用性方面。
2赞 Charlieface 11/15/2023 #2

1. Does this mean that, for example, there will be times when the WHERE clause is executed before the FROM clause and times when the FROM clause is executed first and then the WHERE clause?
If you mean at the logical stage: no, always comes logically before a . It is certainly possible for a filter physically to happen first, for example startup filters which do not depend on the tables. But the result will be the same.
That (rather badly written) Warning in the documentation is warning about runtime errors, especially in the case of (although it can also happen with divide-by-zero and others). What can happen is that the compiler does not take into account possible error conditions, and assumes the query will finish correctly, so it reorders conditions in a way that can cause an error.
The way around such errors is to use constructs which force the ordering, such as , or .
FROMWHEREWHERECONVERTTRY_CONVERTCASENULLIF

2. Can I rely 100% on logical processing to know which objects (columns aliases, tables, etc) I have "available" in subsequent query clauses?
Yes, the SQL grammar enforces what the result of the logical processing should be.

3. So, what is the point of logical processing if physical processing (the database, optimizer, indexes, etc at the end of the day) decides the order of execution in a query?
They are two separate things: logical defines the what: what is the intended result (joins, columns, filters, rowgoals), physical defines the how: how does the compiler construct access methods (indexing), which join strategies, where to place filters, to create that result.

4. Does this mean that physical processing can "skip" (alter, modify, I don't know what the right word is) the logical processing steps?
Yes, it may. There are many ways your query can be transformed, using various optimizations and simplifications. The result should be the same.

5. Does the logical processing is executed first and then the physical processing?, or how?
The compiler will analyze the query according to the grammar to make a logical query plan, then analyze what access methods are available to execute it. Again, two different things.

评论

0赞 jwa 11/15/2023
Hi @Charlieface - So the physical processing has to replicate the result of the logical processing only in a different way?
0赞 jwa 11/15/2023
"logical defines the what, physical defines the how." - what exactly does that refer to? I've seen it a lot around here on StackOverflow? @Charlieface
0赞 Charlieface 11/15/2023
Added more wording. The logical processing means the compiler's understanding of what you want eg you want the results of two joins, with a filter, a rowgoal (TOP) and some columns selected. The physical processing is the actual way the compiler gets that, eg using various indexing and joining strategies. The logical processing doesn't actually exist as such, it's just the understanding of what the query defines.
0赞 jwa 11/15/2023
Can we say that the purpose of the logical processing is only to explain the scoping rules? @Charlieface
0赞 Charlieface 11/15/2023
No it also defines the rest of the query, such as filtering, rowgoals etc. It just doesn't define how that should be achieved.