在我的PL / SQL中有这个使用绑定变量的大动态SQL。我使用DBMS_SQL包来绑定并执行生成的查询。
根据某些条件,where-clause被添加到动态SQL中。当我只使用" in"或者" ="匹配我的绑定变量一切正常,结果返回得非常快。
示例:
(servedparty = :bv_ or servedpartyimsi = :bv_)
但是,当我执行以下操作时:
(servedpartyimei like :bv_)
并提供类似12345679890%的值,查询需要非常长的时间。
我也试过像这样的事情
(servedpartyimei like :bv_||'%')
然后提供没有'%'的值但它给出了相同的结果
当我执行不带绑定变量的查询但只输入硬编码值时,结果也会立即返回。
我在这里做错了吗?不要像LIKE运算符那样绑定变量吗? 有什么想法吗?
谢谢。
答案 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 |||''%''';
谢谢