我有一个连接两个表并应用过滤器的视图。当我运行视图时它需要< 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编辑器中编写表格更容易)
答案 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)
上有一个可用于JOIN
和ORDER 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放入您的视图中。