当前位置: 首页 > 面试题库 >

存储过程SQL执行计划

毕富
2023-03-14
问题内容

我对执行速度非常慢的存储过程有些困惑。该存储过程基本上包含一个使用传入参数(in_id)的查询,并将其放在游标中,如下所示:

open tmp_cursor for 
select col1, col2, col3
from table1 tab
where ((in_id is null) or (tab.id = in_id));  -- tab.id is the PK

当我获得带有预定义值的SQL查询的执行计划时,使用索引可以得到良好的查询结果。但是,当我从应用程序中调用该过程时,我看到没有索引在使用中,并且该表得到了完整扫描,从而降低了性能。
如果删除WHERE子句的第一部分“(in_id为null)”,则应用程序的性能将再次提高。
为什么在我的应用程序调用过程中不使用索引(传入了in_id)?


问题答案:

假设这in_id是一个查询参数-不是列名:

不管输入什么,查询都必须只有一个执行计划。因此,如果将参数传递 in_id为NULL,则应该返回所有行。如果传递非NULL
in_id,则应仅返回单个PK值。

因此,Oracle选择了“最糟糕的”执行程序。计划应对“最坏的情况”。“通用”查询是通向地狱的道路。只需将查询分为两个即可。

select col1, col2, col3
from table1 tab
where in_id is null or in_id is not null;

这将使用全表扫描,这是获取所有行的最佳方法。

select col1, col2, col3
from table1 tab
where tab.id = in_id;  -- tab.id is the PK

这将使用UNIQUE索引扫描,这是获取单个索引行的最佳方法。



 类似资料:
  • 我如何在服务器的另一个存储过程中执行SQL存储过程?我将如何传递第二个过程的参数。?

  • 问题内容: 我想使用Oracle SQL Developer异步执行存储过程很多次。 伪代码 存储过程的目的是进行一些插入。为了进行测试,我只想异步执行存储过程很多次。我不在乎任何返回值。 有没有一种 “简便”的 方法来做到这一点? 问题答案: 由于您要模拟N个会话,每个会话均调用该过程1000 / N次,因此我可能会执行类似的操作 本示例将启动10个会话,每个会话将快速连续执行该过程100次,前

  • 当我试图执行这个存储过程时,我收到了一个错误:“数据库连接器错误:'不允许从数据类型'CHAR'隐式转换为'INT'。使用CONVERT函数运行这个查询“为什么?”?我该怎么解决这个问题?谢谢 这是im用来执行SP的查询: 该列被设置为char(4),因此我不认为查询和数据类型不匹配 顺便说一句,我试过使用单引号、双引号和不使用引号的(“7066”),但仍然得到相同的sql错误。请帮忙 PS我在用

  • 问题内容: 我们在应用程序中创建了许多效率低下的存储过程,我们总是将其推迟以提高其效率,直到我们对数据库性能遇到严重的问题为止。 现在,我正在考虑通过最常执行的存储过程一一修复它。 找出哪个存储过程最执行的最佳方法是什么? 是否有一个脚本可以显示哪个存储过程执行得最多? 问题答案: 使用: 参考:SQL SERVER‘2005’查找最高/最常使用的存储过程

  • 在尝试使用JPA在Oracle中执行存储过程时,出现以下异常: 原因:组织。开关站。HandlerException:java。lang.NoSuchMethodError:javax。坚持不懈实体管理器。createStoredProcedureQuery(Ljava/lang/String;) 有一个代码段:

  • 我一直试图使用Hibernate执行Oracle存储过程。这不是用于生产,而是用于我正在研究的Java源代码解析项目。简单地说,我不能从Oracle存储过程返回值。 我搜索并阅读了SO、Hibernate Community/Documentations(原生SQL章节)链接中的所有相关链接,并尝试了这些建议,但不知何故无法让它们发挥作用。以下是我的来源--我只包括相关的部分。