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 回答