1

これが他の場所に答えがある場合は、事前にお詫び申し上げます-一生懸命探しましたが、見つかりませんでした.

次のような「item」というテーブルがあります。

itemid applicationid value
   1        1        3.00
   2        2        1.00
   3        2        2.00
   4        3        4.00
   5        3        1.00

つまり、アプリケーションは複数のアイテムを持つことができます。他にも列がありますが気にしないでください。アプリケーションの合計値に対するアイテムとその値をリストしたいと思います (アイテムの値をアプリケーションの割合として計算できるようにするため)。

だから私はこのようなクエリを少し持っています:

SELECT i.itemid, i2.applicationid, i.value, i2.totalvalue
FROM item i
JOIN (SELECT sum(value) AS totalvalue FROM item GROUP BY applicationid) i2
    ON i.applicationid = i2.applicationid
WHERE <some criteria that returns a hundred or so items>;

私に与える為に

itemid applicationid value totalvalue
   1        1        3.00     3.00
   2        2        1.00     3.00
   3        2        2.00     3.00
   4        3        4.00     5.00
   5        3        1.00     5.00

これは機能しますが、item テーブルに 10 万行あると非常に遅くなります。プロファイラーから、問題はフル インデックス スキャンを実行しているサブクエリにあると言われました。

GROUP BY を使用した自己結合の方が速いのではないかと思いましたが、2 番目のテーブルだけでなく、全体をグループ化します。いえ

SELECT i.itemid, i2.applicationid, i.value, sum(i2.value)
FROM item i
JOIN item i2 ON i2.applicationid = i.applicationid
WHERE <some criteria that returns a hundred or so items>
GROUP BY i2.applicationid;

itemid ごとに 1 行ではなく、applicationid ごとに 1 行しか取得できません。

元のクエリを書き直して高速化する方法はありますか?

どうもありがとう。

4

2 に答える 2

1

クエリにはサブクエリへの結合条件がないため、構文的に正しくありません。このクエリを試しましたか:

SELECT i.itemid, i2.applicationid, i.value, i2.totalvalue
FROM item i JOIN
      (SELECT applicationid, sum(value) AS totalvalue
       FROM item
        GROUP BY applicationid
     ) i2
     on i.applicationid = i2.applicationid
WHERE <some criteria that returns a hundred or so items>; 

一部のデータベースでは、特に applicationid にインデックスがある場合、これは相関サブクエリとしてより高速に実行される可能性があります。

SELECT i.itemid, i.applicationid, i.value,
       (select sum(value) from item i2 where i.applicationid = i2.applicationid
       ) as totalvalue
FROM item i JOIN
      (SELECT applicationid, sum(value) AS totalvalue
       FROM item
        GROUP BY applicationid
     ) i2
     on i.applicationid = i2.applicationid
WHERE <some criteria that returns a hundred or so items>; 

また、データベースによっては、再び速度を低下させているのは WHERE 条件である可能性があります。

于 2012-08-20T17:54:12.243 に答える
-1

ウィンドウ関数を使用して、オプティマイザがそれらを適切に使用しているかどうかを確認できます。同じ実行計画を使用すると思いますが、簡単に試してみる価値があります。これは SQL Server のコードであり、Oracle の場合も同様です。

SELECT i.itemid, i.applicationid, i.value, 
    sum(value) Over (Partition by i.applicationid) as totalvalue
FROM item i
WHERE <some criteria that returns a hundred or so items>;
于 2012-08-20T16:55:06.953 に答える