【问题标题】:use bind variable with LIKE % operator将绑定变量与 LIKE % 运算符一起使用
【发布时间】:2017-04-01 08:05:37
【问题描述】:

在我的 PL/SQL 中有这个使用绑定变量的大动态 SQL。我使用 DBMS_SQL 包来绑定和执行生成的查询。

根据某些条件,将 where 子句添加到动态 SQL 中。当我只使用“in”或“=”来匹配我的绑定变量时,一切正常并且返回结果非常快。

例子:

(servedparty = :bv_ or servedpartyimsi = :bv_)

但是,当我执行以下操作时:

(servedpartyimei like :bv_)

并提供像 12345679890% 这样的值,查询需要非常非常长的时间。

我也试过这样的方法

(servedpartyimei like :bv_||'%')

然后提供不带“%”的值,但结果相同

当我在没有绑定变量但只输入硬编码值的情况下执行查询时,结果也会立即返回。

我在这里做错了吗?不要像 LIKE 运算符那样绑定变量? 有什么想法吗?

谢谢。

【问题讨论】:

  • servedpartyimei 是什么数据类型?您已经显示了一个数字的搜索值(我认为这对 IMEI 有意义?)但您将其视为字符串。您可能还需要说明您使用的是哪个版本的 Oracle;你能看看快速和慢速版本的执行计划吗?
  • imei 以字符串形式存储在数据库中。数据库版本为 11.2
  • 您仍然需要查看执行计划以了解它在做什么。也许在它认为更合适的其他(索引)列上也有过滤器,或者由于其他原因没有使用您期望的索引。我们无法真正猜测它在做什么,您需要找出答案。
  • 检查了执行计划,它们是相似的。当我在不同的环境中执行相同的 PL/SQL 时(问题发生在我们的 DEV 上,现在在 TEST 上尝试)结果会立即返回。所以这可能是一个环境问题。将与 DBA 核实

标签: oracle plsql sql-like bind-variables


【解决方案1】:

我认为您遇到了 Oracle 错误 9197434(使用 DBMS_SQL 时不会发生 BIND PEEKING)

据我所知,这还没有解决。

如果没有绑定变量窥视的好处,Oracle 不知道LIKE 条件右侧的值是什么。例如,它可能只是“%”。因此,Oracle 假设有多少行将是LIKE 一个典型的绑定变量值。这些假设非常保守,可能会迫使 Oracle 从您想要的快速计划(可能使用索引)转向您获得的慢速计划(可能使用散列连接)。

如果可能,我建议您使用本机动态 SQL(即EXECUTE IMMEDIATE),因为它不会受到此错误的影响。否则,您可能需要提示您的 SQL。

【讨论】:

  • 同一错误的 11.2 版本是错误# 13386678(BIND PEEKING 在 DBMS_SQL 中不起作用)。 Oracle 将该错误关闭为“无法修复”。因此,您需要一种解决方法。
【解决方案2】:

当您将 LIKE 与绑定变量一起使用时,在某些旧版本中,Oracle 必须假设有多少行将匹配。我不记得它选择了什么值(它可能因版本而异)它可能是 5%、10% 等等。现在这可能与现实不符,并导致计划不佳。

有一个名为_like_with_bind_as_equalityundocumented(和unsupported)优化器参数,正如其名称所暗示的那样 - 即当设置为true 时假定行数column like :bv 返回的与 column = :bv 返回的相同。因此,如果您使用它,您可能会获得更快的计划。您可以通过alter session进行设置。

【讨论】:

  • 试图这样做,但不幸的是它没有效果。
【解决方案3】:

我遇到了同样的问题,我尝试了下面提到的,似乎工作正常

V_QUERY := V_QUERY||' AND FIRST_NAME LIKE ''%''||:VAR2||''%''';

谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 2022-11-17
    • 1970-01-01
    相关资源
    最近更新 更多