调整Rows-to-Cols查询

时间:2009-09-15 23:40:20

标签: sql oracle plsql performance

以下查询(V_TITRATION_RESULTS)是一个视图使用行到列的数据透视表,它返回大约20,000行:

SELECT test.created_on as "Created On", 
       r_titr as "Titrator", 
       r_fact as "Factor" 
  FROM (SELECT test_id, 
               MAX(CASE WHEN result_tmpl_id = 2484 THEN result END) r_titr, 
               MAX(CASE WHEN result_tmpl_id = 2483 THEN result END) r_fact 
          FROM (SELECT lims.test.* 
                  FROM lims.test 
                 WHERE test_tmpl_id = 867) 
          JOIN lims.result USING (test_id) 
      GROUP BY test_id) 
  JOIN lims.test test USING (test_id)

我想搜索自9月初以来仅返回测试的视图:

SELECT * FROM V_TITRATION_RESULTS WHERE "Created On" > DATE '2009-09-01'

视图和筛选查询的“获取计划”是相同的,并且两个查询的跟踪统计信息(如下所示)类似,表示在处理完所有行之前不会对这些行进行过滤。

                   VIEW     Filtered      Diff
Physical Reads    81730        83946      2216
Logical Reads    364488       344063    -20425
Sort Rows        632194       632193        -1
ROWID Gets       580778       580778         0
Chained Gets     101823       101823         0
Memory (kB)         307          324        17
Scan Rows             3            3         0
Scan Gets             3            3         0
Sorts In Mem          4            4         0
Temp Segments         1            1         0
Scan Short            3            3         0
CPU Total (sec)    8.13          7.3     -0.83
First Row        2m 12s       2m 40s    
Last Row            18s           0s    

如何重写我的视图,以便WHERE条件在行到列数据透视之前过滤测试?

2 个答案:

答案 0 :(得分:3)

史蒂文,我想知道为什么你不能使用:

CREATE OR REPLACE VIEW V_TITRATION_RESULTS AS 
  SELECT lt.test_id, 
         lt.created_on,
         MAX(CASE WHEN result_tmpl_id = 2484 THEN result END) 'titrator', 
         MAX(CASE WHEN result_tmpl_id = 2483 THEN result END) 'factor'
    FROM lims.test lt 
    JOIN lims.result USING (test_id) 
   WHERE lt.test_tmpl_id = 867 
GROUP BY lt.test_id, lt.created_on

删除子选择将提高查询性能。假设Oracle 9i + - 请注意,您可以在视图中使用Subquery Factoring (WITH clause)

然后你可以使用:

SELECT vtr.* 
  FROM V_TITRATION_RESULTS vtr
 WHERE vtr.created_on > TO_DATE('2009-09-01', 'YYYY-MM-DD')

答案 1 :(得分:1)

这有点超出我的领域,但请考虑在SELECT语句中使用绑定变量而不是文字作为提高性能的方法。

请参阅http://www.akadia.com/services/ora_bind_variables.htmlhttp://www.dba-oracle.com/concepts/views.htm。具体来说,谓词推送的部分可能是您感兴趣的。