1

假设我有以下 SQL 查询,涉及“AS ...”阶段的浮点运算。

SELECT

T1.A * T2.B *  T1.D1 * T3.C AS A1
T1.A * T2.B *  T1.D2 * T3.C AS A2
(...)
T1.A * T2.B * T1.D100 * T3.C  AS A100

FROM TableName1 as T1
INNER JOIN TableName2 AS T2
LEFT JOIN  TableName3 AS T3

其中 TableName 有 5.000.000 行,A、BC 和 D 是来自 A 的行,它们因行而异。2个问题:

1 - A * B * C会实际执行100 次吗?2 - 有没有办法将A * B * C运算分解为 2 次循环乘法只对一行的 100 列执行一次?

此外,我们可以认为“B”例如是一个复杂的函数调用 (SQRT(ARTCTAN(...(x))),因此每只执行一次是合法的。

4

2 回答 2

3

I would assume it would pre-calculate what it can (SQL Server), and then apply that to the column(s).

I'm pretty sure if you put the multiplied numbers in a single-row, cross joined select, that would do it. something like:

select D1 * res
from tableName
cross join (select A * B * C as res) as multiplied

EDIT

If the data is in columns, not scalar values, then maybe:

select t1.D1 * myAlias.res, t1.D2 * myAlias.res, t1.D3 * myAlias.res
from tableName t1
inner join 
    (
    select t2.keyCol, t2.A * t2.B * t2.C as res
    from tableName t2
    ) myAlias 
on t1.keyCol = myAlias.keyCol
于 2012-06-27T12:59:34.553 回答
0

一种方法可能是在表上创建一个计算列。在 SQL Server 中,这看起来像:

CREATE TABLE TableName
 (
   A  float  not null
  ,B  float  not null
  ,C  float  not null
  ,AxBxC  AS  A * B * C
 )

该列将(好的,应该,这取决于 RDBMS 的实现方式)每行读取一次计算一次,之后每次都使用。作为计算列,公式为表存储一次,因此不会显着增加存储空间。


更新更新问题:

您现在正在执行涉及 5,000,000 行的三向表连接(外连接,不少于)。这将很容易达到 10 秒甚至 100 兆字节的磁盘 I/O(除非数据是从之前的读取中缓存的),并且需要合并、循环、散列连接等等来链接所有数据。当所有这些都完成时,相比之下,执行单纯的算术运算所需的 CPU 量将变得微不足道。CPU擅长数学。

要对此进行测试:

  • 如您的问题所示,构建并运行“完整”查询
  • 构建并运行返回A * B* C 计算的查询。
  • 获取“calc once”查询,并将其用作连接到“base”查询的子查询或临时表。

最后一种是我能想到的强制 SQL 每行只执行一次计算的唯一方法。但是,这会引发额外的连接(跨越 500 万行),并且从我所见过或读过的所有内容来看,这是您的性能将受到最大影响的地方。

(如果你做这个测试,我很想看到结果!)

于 2012-06-27T13:08:12.087 回答