Sql 将行调整为Cols查询

Sql 将行调整为Cols查询,sql,oracle,plsql,performance,Sql,Oracle,Plsql,Performance,以下查询(V\u滴定结果)是一个使用行到列透视的视图,该透视返回大约20000行: 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,

以下查询(
V\u滴定结果
)是一个使用行到列透视的视图,该透视返回大约20000行:

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
条件将在行到列透视之前过滤测试?

这有点超出我的范围,但请考虑在SELECT语句中使用绑定变量而不是文本作为提高性能的手段


见和。具体来说,谓词推送部分可能会引起您的兴趣。

这有点超出我的范围,但请研究在SELECT语句中使用绑定变量而不是文本作为提高性能的方法


见和。具体来说,谓词推送部分可能会引起您的兴趣。

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

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+-请记住,您可以在视图中使用它

然后你可以使用:

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

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

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+-请记住,您可以在视图中使用它

然后你可以使用:

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

@大卫:你不能用绑定变量VIEW@rexem:不是在视图本身中,而是在引用该视图的SELECT语句中。@David:这很公平,但该视图在进行任何其他优化之前需要进行优化。@David:不能在视图中使用绑定变量VIEW@rexem:不在视图本身中,但是在引用该视图的SELECT语句中。@David:这很公平,但首先需要优化的是该视图。如果我需要几个其他测试字段(比如10个),那么按所有需要的列分组是否仍然是最有效的(仍然允许筛选),即使只按PK(测试id)分组就足够了?@Steven:您必须按所有列分组,而不必对它们运行聚合函数;MySQL是我所知道的唯一一个与它的错误无关的数据库。我过去常常只按PK分组,然后重新加入表以获取字段(如主要问题中所示)。不进行外部筛选时,性能似乎是相同的,但在筛选时,按所有所需字段分组时,性能更高。Oracle是否足够聪明,知道PK是group by列中的一个,并且只与它进行比较?(即:如果两行共享同一主键,则行共享所有列。)@Steven:尝试在SELECT(和GROUP BY)中公开额外的列,而不是再次加入到表中。如果我需要几个其他测试字段(比如10个),按所有需要的列分组是否仍然是最有效的(以允许进行筛选)即使只按PK(test_id)分组就足够了?@Steven:您必须按所有列分组,而不针对它们运行聚合函数;MySQL是我所知道的唯一一个与它的错误无关的数据库。我过去常常只按PK分组,然后重新加入表以获取字段(如主要问题中所示)。不进行外部筛选时,性能似乎是相同的,但在筛选时,按所有所需字段分组时,性能更高。Oracle是否足够聪明,知道PK是group by列中的一个,并且只与它进行比较?(即:如果两行共享同一主键,则两行共享所有列。)@Steven:尝试公开SELECT(和GROUP BY)中的其他列,而不是再次加入表中。