1

次のクエリは機能しますが、特に高速ではありません。

select distinct controlid, (
                select max(Orderno) From my_table
                Where ControlID = #param1#
                    and a = 3 and b = 13 and c = 0 and d = 0
            ) colA, (
                Select max(Orderno) From my_table
                Where ControlID = #param1#
                    and a = 2
            ) colB, (
                Select max(Orderno) From my_table
                Where ControlID = #param1# 
                    and a = 1 and b = 14 and e = 1
            ) colC, (
                Select max(Orderno) From my_table
                Where ControlID = #param1# 
                    and a = 3 and b = 13 and e = 1 and c = 0 and d = 0
            ) colD, (
                Select a From my_table
                Where ControlID = #param1#
                    and Orderno = #param2#  
            ) colE
            from my_table
            where controlid = #param1#

クエリ対象のテーブルには 300K を超える行があり、特定の controlid (distinct 句の前) の行数は 1 から 61 までさまざまです。プロファイラーによると、応答時間は 234/42 ミリ秒です。テーブルにインデックスはありません。

明らかに、インデックスの欠如は問題ですが、それ以上に、このクエリを作成するためのより効率的な方法を推奨できる人はいますか?

4

2 に答える 2

4

サブクエリの代わりに集計を使用します。

select distinct controlid, 
  max (case when a=3 and b=13 and c=0 and d= 0 then OrderNo end) as colA,
  max (case when a=2                           then OrderNo end) as colB,
  max (case when a=1 and b=14 and e=1          then OrderNo end) as colC,
  max (case when a=3 and b=13 and e=1 and c=0 and d=0 then OrderNo end) as colD,
  max (case when OrderNo=#param2# then a end) as colE
from my_table
where controlid = #param1#
group by controlid

どの RDBMS を使用しているかはわかりません。そのため、case when構成をローカルの方言に合わせて変更する必要があるかもしれません。これは MSSQL に有効なはずです

更新: メガネが正しく機能しないため、ORACLE タグに気づきませんでした。恥ずかしい...

于 2013-03-06T19:26:18.897 に答える
3

テーブルに複数回ヒットすることを避け、単一のテーブルスキャンを実行できるはずです

SELECT controlID,
       MAX( CASE WHEN a = 3
                  AND b = 13
                  AND c = 0 
                  AND d = 0
                 THEN orderNo
                 ELSE NULL
              END) colA,
       MAX( CASE WHEN a = 2
                 THEN orderNo
                 ELSE NULL
              END) colB,
       MAX( CASE WHEN a = 1
                  AND b = 14
                  AND e = 1
                 THEN orderNo
                 ELSE NULL
              END) colC,
       MAX( CASE WHEN a = 3
                  AND b = 13
                  AND e = 1
                  AND c = 0
                  AND d = 0
                 THEN orderNo
                 ELSE NULL
              END) colD,
       MAX( CASE WHEN orderNo = #param2#
                 THEN a
                 ELSE NULL
              END) colE
  FROM my_table
 WHERE controlId = #param1#
 GROUP BY controlID

もちろん、テーブルに適切なインデックスを作成し、複数のインデックス スキャンを実行する方が効率的である可能性があります。データを知らなければ、それを知ることは困難です。

于 2013-03-06T19:28:15.517 に答える