将bind变量与LIKE%运算符

时间:2016-11-17 16:53:29

标签: oracle plsql sql-like bind-variables

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

根据某些条件,where-clause被添加到动态SQL中。当我只使用" in"或者" ="匹配我的绑定变量一切正常,结果返回得非常快。

示例:

(servedparty = :bv_ or servedpartyimsi = :bv_)

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

(servedpartyimei like :bv_)

并提供类似12345679890%的值,查询需要非常长的时间。

我也试过像这样的事情

(servedpartyimei like :bv_||'%')

然后提供没有'%'的值但它给出了相同的结果

当我执行不带绑定变量的查询但只输入硬编码值时,结果也会立即返回。

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

谢谢。

3 个答案:

答案 0 :(得分:4)

我认为您正在遭受Oracle错误9197434(在使用DBMS_SQL时不会发生并且不会发生)

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

如果没有绑定变量偷看的好处,Oracle就不知道LIKE条件的右侧会有什么值。例如,它可能只是'%'。因此,Oracle假设有多少行LIKE是典型的绑定变量值。这些假设非常保守,很可能迫使Oracle远离您想要的快速计划(可能使用索引)来实现您正在获得的缓慢计划(可能使用散列连接)。

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

答案 1 :(得分:3)

当您对绑定变量使用LIKE时,在某些旧版本中,Oracle必须假设将匹配多少行。我无法记住它选择的价值(可能因版本而异)可能是5%,10%,无论如何。现在这可能与现实脱节并导致糟糕的计划。

有一个未记录的(和不支持的)优化器参数,名为_like_with_bind_as_equality,它的名称表明了这一点 - 即设置为true时假设column like :bv返回的行数与column = :bv返回的行数相同。因此,如果你使用它,你可能会得到一个更快的计划。您可以通过alter session设置它。

答案 2 :(得分:0)

我遇到了同样的问题,我尝试了如下所述的操作,并且看起来工作正常

V_QUERY:= V_QUERY ||' AND FIRST_NAME就像``%''|| :: VAR2 |||''%''';

谢谢