【问题标题】:Query on View is running slower than direct query - in Oracle视图上的查询比直接查询运行得慢 - 在 Oracle 中
【发布时间】:2013-12-30 20:26:06
【问题描述】:

我尝试使用参数创建视图以动态获取数据。
(我不能使用 WHERE 条件,因为 select 语句本身会根据参数而变化)

为此,我编写了一个程序,它将所需的数据作为 oracle 对象类型返回给我。

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 * FROM TABLE(get_data(12345, 'MYTAB'));

这会在 不到 1 秒内为我提供数据。

对于相同的选择语句,我创建了一个视图

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

如果我查询视图

SELECT * FROM my_view

获取相同数据需要 6 秒以上

知道为什么查询相同的数据会有如此大的差异。
veiw 会比普通查询花费更多时间吗?

【问题讨论】:

  • 一个完全可复现的测试用例在这里会大有帮助。一般来说,只需在某些东西上添加select * from 并不重要。我们需要确切知道是什么让您的案例与众不同。
  • @jonearles:正如 Guntram Blohm 所说,当我从视图中查询时,它正在执行全表扫描,而直接查询使用基表的所有索引来更快地获取数据。
  • 这很有帮助,但我们还没有找到问题的根源。我想知道为什么它使用 FTS 而不是索引。

标签: sql performance oracle view object-type


【解决方案1】:

谷歌“解释计划”,并检查两个语句的执行计划。没有完整的功能,很难说什么。但是我假设优化器在视图上做了一些“通用优化”,当你从视图中选择时,就会使用通用优化。当您直接选择而不使用视图时,优化器也会考虑您的函数的内部结构。

尝试对从视图中选择的不同语句解释计划。执行功能的“内部部分”是否在每种情况下都相同?

【讨论】:

  • 是的,我发现视图和直接查询的解释计划存在巨大差异。使用表上的所有索引直接查询,其中视图执行全表扫描。
  • 在函数的“内部部分”中,其中条件因参数而异。它们将被动态附加并执行最终查询以获取结果
【解决方案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。

【讨论】:

  • 还要注意,V_$SQL... 视图而不是 V$SQL... 需要授予权限...这是因为 V$SQL 视图实际上是同义词。但是,您可以从这些同义词中进行选择。
猜你喜欢
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多