2

我正在玩 SQL 查询,我想到了这个 - select x,y from table T.

这里 x 和 y 可以是算术表达式,例如 2.0/5.0 OR 1+2,结果是表 T 的行数,第一列的值为 2.0/5.0,即 0.444444,第二列的值为 3。

我很想知道这个查询是如何执行的。我了解到,在 SQL 查询引擎中,存在从查询的 SQL 表示到内部表示(如关系代数)的映射,然后对其进行优化以产生最佳的查询执行计划。

如果它是错误的,请纠正我的理解 - 对于我所说的查询,从我的查询 Q 到内部表示之间会有一个内部映射,它相当于select * from table T. 然后对于所有返回的行,n 个列被投影出来,其中 n 是 Q 中所述的算术表达式的数量。n 列的所有行都将具有它们各自对算术表达式的评估。

干杯

4

6 回答 6

1

它很可能取决于数据库。

如果您用于 x 和 y 的表达式是常量,那么一个体面的数据库应该能够识别并只执行一次计算并将值放入结果集中。

如果表达式包含其他函数,那么每次都必须执行表达式,以防函数产生副作用。

一般来说,您是正确的,计算 from 子句中描述的虚拟表,然后我相信 where 子句中的过滤器被应用,然后是 select 子句。

于 2009-05-22T19:41:13.777 回答
1

不,表达式只计算一次(至少在 MS SQL Server 中)。

如果你这样做,你可以很容易地看到这一点:

select rand() from tableT

所有行都将具有相同的随机数。

于 2009-05-22T19:42:28.830 回答
1

它将扫描,因为没有 where 子句。这是 sql server 的set showplan_all on

select 2.0/5.0,1+2 from YourTable                                                            
  |--Compute Scalar(DEFINE:([Expr1003]=(0.400000), [Expr1004]=(3)))                           
       |--Index Scan(OBJECT:([wppusdev].[dbo].[AP_Voucher].[YourTable_Index]))
于 2009-05-22T19:54:10.600 回答
0

从 MS SQL 的角度来看...

它的评估结果可能与 SELECT * FROM Table 不同,因为引擎应该意识到它实际上并不需要表中的任何列,因此它很可能会选择表上最薄的索引并对其进行扫描。

实际方程只应评估一次,然后将其用作常数。

于 2009-05-22T19:57:49.143 回答
0

PostgreSQL 将首先评估表达式,然后很可能对表执行顺序扫描。此外,正如其他地方所提到的,许多 SQL 风格都有一个 EXPLAIN 关键字,它将向您展示在给定当前实现的情况下如何评估特定查询。

于 2009-05-22T20:01:16.187 回答
0

数据库是否为每一行评估一次函数是一个实现决定。在 Oracle 中,您可以从表中选择 dbms_random.random() 并为每一行返回不同的数字。例如,如果您想以随机顺序返回行,这将很有帮助。

于 2009-05-22T20:10:18.867 回答