1

「AS ...」ステージでの浮動小数点演算を含む、次の SQL クエリがあるとします。

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 -行の 100 列に対して 1 回だけ実行される 2 つの反復乗算のA * B * C演算を因数分解する方法はありますか?

また、「B」はたとえば複雑な関数呼び出し (SQRT(ARTCTAN(...(x))) であると考えることができるため、ごとに 1 回だけ実行する正当性があります。

4

2 に答える 2

3

私は、それができること(SQL Server)を事前に計算し、それを列に適用すると思います。

乗算された数値を単一行の交差結合選択に入れれば、それでうまくいくと確信しています。何かのようなもの:

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

編集

データがスカラー値ではなく列にある場合、おそらく次のようになります。

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

1 つの方法は、テーブルに計算列を作成することです。SQL Server では、次のようになります。

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

列は ( RDBMS がどのように実装されているかによって異なります)、行の読み取りごとに 1 回計算され、その後は毎回使用されます。計算された列として、数式はテーブルに対して 1 回保存されるため、ストレージ スペースが大幅に増加することはありません。


更新された質問の更新:

現在、5,000,000 行を含む 3 者間テーブル結合 (外部結合以上) を実行しています。これは簡単に数十メガバイト、おそらく数百メガバイトのディスク I/O に達し (データが以前の読み取りからキャッシュされていない場合)、マージ、ループ、ハッシュ結合、およびすべてのデータをリンクするためのその他の操作が必要になります。それがすべて完了する頃には、単純な算術演算を実行するために必要な CPU の量は、比較すると取るに足らないものになります。CPUは数学が得意です。

これをテストするには:

  • 質問のように、「完全な」クエリを作成して実行します
  • A * B* C の計算のみを返すクエリを作成して実行します
  • 「calc once」クエリを取得し、それを「base」クエリに結合されたサブクエリまたは一時テーブルとして使用します。

最後の方法は、SQL で行ごとに 1 回だけ計算を実行するように強制する唯一の方法です。ただし、これは追加の結合 (500 万行にまたがる) をスローし、私がこれまでに見たり読んだりしたすべてのことから、パフォーマンスが最も低下する場所です。

(もしあなたがこのテストをしたら、私は結果を見てとても興味があります!)

于 2012-06-27T13:08:12.087 に答える