2013-12-12 177 views
3

我试图创建视图的参数来动态获取数据。
查询查询运行速度比直接查询慢 - 在Oracle

对于这一点,我写了返回我所需要的数据,Oracle对象类型的程序(WHERE条件的select语句本身的变化基于参数我不能使用)。

FUNCTION get_data(p_pk_id NUMBER, p_tab_type VARCHAR2) 
RETURN M_TYPE_DATA_TAB 
AS 
v_table_collection M_TYPE_DATA_TAB; 
BEGIN 

-- my sql query which will change based on the params 

RETURN v_table_collection; 
END; 

我按如下方式运行select查询。

SELECT * FROM TABLE(get_data(12345, 'MYTAB')); 

这使我数据在小于1秒

为我创建了一个视图相同的SELECT语句

CREATE OR REPLACE VIEW my_view 
AS SELECT * FROM TABLE(get_data(12345, 'MYTAB')); 

如果我查询视图

SELECT * FROM my_view 

需要超过6秒获得相同的数据。

任何想法为什么有这么大的差异来查询相同的数据。
请问veiw比普通查询需要更多时间吗?

+0

一个完全可重复的测试案例在这里会有很大的帮助。通常只要在某个东西上添加'select * from'就没有关系。我们需要确切知道它是什么使你的案例变得特别。 –

+0

@jonearles:正如Guntram Blohm所说,当我从视图查询时,它正在执行全表扫描,其中直接查询使用基表的所有索引来更快地获取数据。 –

+0

这很有帮助,但我们还没有找到问题的根源。我想知道*为什么*它使用FTS而不是索引。 –

回答

2

每条语句的执行计划会给你更多的细节。尝试使用一些提供的oracle工具来调查每种情况下究竟发生了什么。

尝试做一:

SELECT/*+gather_plan_statistics*/ * FROM TABLE(get_data(12345, 'MYTAB')); 

然后执行:

SELECT/*+gather_plan_statistics*/ * FROM my_view 

这会给你的语句实际执行计划。

顺便说一下,您需要在V_ $ SQL_PLAN和V_ $ SQL视图上选择使用上述gather_plan_statistics。

+0

还要注意,V_ $ SQL ...视图而不是V $ SQL需要授予...这是因为V $ SQL视图实际上是同义词。然后,您可以从这些同义词中进行选择。 –

1

Google用于“解释计划”,并检查两种语句的执行计划。没有完整的功能,很难说什么。但我假设优化器在视图上进行了一些“通用优化”,并且当您从视图中选择时,将使用该通用优化。当您直接选择而没有视图时,优化器也会考虑函数的内部。

尝试从视图中选择不同语句的解释计划。执行功能的“内部部件”是否相同?

+0

是的,我发现查看和直接查询的解释计划有很大的不同。直接使用表上的所有索引进行查询,作为执行全表扫描的视图。 –

+0

位于函数的“内部部分”中,其中条件因参数而异。他们将被动态追加并且最终查询将被执行以获取结果 –