使用游标参数会导致不同的执行计划?

时间:2015-08-11 13:51:36

标签: oracle plsql cursor

出于某种原因,我试图弄清楚为什么以下查询通过全表扫描执行,这需要很长时间,因为该表有~31M行

PROCEDURE d1(k_uni_in IN data_par.k_uni%TYPE) AS
  CURSOR d1_cur IS
  SELECT d.*
  FROM data_par d
  WHERE d.k_uni = k_uni_in
  ORDER BY d.k_date;
BEGIN
  FOR i IN d1_cur LOOP
    ...
  END LOOP;
END;

然而看似相似的查询运行索引范围扫描并且几乎是即时的

PROCEDURE d1(k_uni_in IN data_par.k_uni%TYPE) AS
  CURSOR d1_cur(k_cv IN data_par.k_uni%TYPE) IS
  SELECT d.*
  FROM data_par d
  WHERE d.k_uni = k_cv
  ORDER BY d.k_date;
BEGIN
  FOR i IN d1_cur(k_uni_in) LOOP
    ...
  END LOOP;
END;

为什么会这样?我应该总是使用游标参数而不是在游标中使用suprogram参数吗?

1 个答案:

答案 0 :(得分:0)

如果您的表DATA_PAR有一个名为K_UNI_IN的列,那么Oracle正在解释这一行:

WHERE d.k_uni = k_uni_in

意思是

WHERE d.k_uni = d.k_uni_in

而且,由于这显然不是索引可以提供帮助的条件,因此您需要进行全表扫描。

另请参阅:http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/nameresolution.htm#LNPLS2038