ORDER BY在视图上较慢而不是直接SELECT

时间:2015-11-26 16:05:18

标签: sql oracle oracle11g

我有一个连接两个表并应用过滤器的视图。当我运行视图时它需要< 2s,当我运行与直接SELECT而不是视图相同的语句时,它也需要< 2s。

令人困惑的部分是,如果我在从视图中选择时添加订单,则查询需要> 20秒,其中将订单直接添加到查询中需要< 2s

我的代码看起来有点像这样:

创建视图:

CREATE VIEW MY_VIEW AS 
SELECT T1.COLUMN1, T2.COLUMN 2
FROM TABLE1 T1, TABLE2 T2 
WHERE T1.COLUMN3=T2.COLUMN3

查询视图(< 2s):

SELECT * FROM MY_VIEW

直接查询没有视图(< 2s)

SELECT T1.COLUMN1, T2.COLUMN 2
FROM TABLE1 T1, TABLE2 T2 
WHERE T1.COLUMN3=T2.COLUMN3

使用ORDER BY(> 20s)查询视图

SELECT * FROM MY_VIEW ORDER BY COLUMN1

使用ORDER BY(< 2s)

查询视图
SELECT T1.COLUMN1, T2.COLUMN 2
FROM TABLE1 T1, TABLE2 T2 
WHERE T1.COLUMN3=T2.COLUMN3 
ORDER BY T1.COLUMN1

关于如何更有效地订阅视图,您有什么建议吗?或者是废弃使用视图并坚持直接SELECT的唯一选择。

计划分别如下(对不起它的图像,我发现它比在StackOverflow编辑器中编写表格更容易)

SELECT ON THE VIEW

SELECT ON THE ORIGINAL TABLES DIRECTLY

SELECT ON THE VIEW WITH ORDER BY

SELECT ON THE ORIGINAL TABLES DIRECTLY WITH ORDER BY

3 个答案:

答案 0 :(得分:1)

您面临的问题是编译了视图定义。编译查询时设置查询的执行计划,而不是在使用它时设置。

正如您所观察到的,最佳执行计划:

SELECT T1.COLUMN1, T2.COLUMN2
FROM TABLE1 T1 JOIN
     TABLE2 T2 
     ON T1.COLUMN3 = T2.COLUMN3;

与最佳执行计划不同:

SELECT T1.COLUMN1, T2.COLUMN2
FROM TABLE1 T1 JOIN
     TABLE2 T2 
     ON T1.COLUMN3 = T2.COLUMN3
ORDER BY T1.COLUMN1;

(如果我不得不猜测,TABLE1(COLUMN1, COLUMN3)上有一个可用于JOINORDER BY的索引,但Oracle优化器可能会选择另一个执行路径ORDER BY。)

你能做什么?首先,您可以尝试重新编译视图。如果基础数据已更改,则执行计划可能不是最佳的。其次,您可以在查询中插入提示以强制执行特定计划。

答案 1 :(得分:0)

如果您尝试从具有大量连接条件的大型卷表中选择数据,建议使用WITH子句。它肯定减少了订购DIRECT查询的过载。

CREATE OR REPLACE FORCE VIEW MY_VIEW        
AS                                          
WITH TEMP_AV AS                             
  (SELECT T1.COLUMN1,                       
    T2.COLUMN 2                             
  FROM TABLE1 T1,                           
    TABLE2 T2                               
  WHERE T1.COLUMN3=T2.COLUMN3               
  )                                         
SELECT * FROM TEMP_AV A ORDER BY A.COLUMN1; 

答案 2 :(得分:-2)

为了让您按顺序排序,它需要返回所有内容,然后对其进行排序,并且无法访问索引。

在直接选择中使用Order By可以直接使用索引。

建议。将Order By放入您的视图中。