当我得到以下查询的解释计划时,我看到,两个表都具有全表扫描功能。
SELECT *
FROM employees e,
departments d
WHERE e.employee_id = d.manager_id;
这是我通过explain plan命令获得的解释计划。 by EXPLAIN PLAN FOR command
https://i.hizliresim.com/JZdB2o.jpg https://hizliresim.com/JZdB2o https://pasteboard.co/HO9ARcl.jpg
但是,如果我得到了与SQL开发人员相同查询的解释计划,那么我会看到一个明显不同的解释计划。 尤其是,它会在表头完全写入表访问权限,但是在表头上方,它会按索引rowid写入表访问权限。
这是我从SQL Developer获得的解释计划。 by SQL Developer Explain Plan button
https://i.hizliresim.com/DYoYbv.jpg https://hizliresim.com/DYoYbv https://pasteboard.co/HO9BxfA.jpg
我的问题是,谁能逐步解释SQL开发人员的解释性计划?为什么SQL Developer和explain plan命令会生成不同的解释计划?
谢谢。
答案 0 :(得分:2)
有几种不同的方法可以在SQL Developer中获得查询计划。
您使用哪种方法?您已裁剪好图片,以至于我们无法确定这是V $ SQL_PLAN的缓存计划还是Explain Plan。
现在,问题的症结所在-不要使用解释计划。这可能是不可靠的。它向您显示可以运行的计划-它没有向您显示曾经或将要使用的实际计划。
还要在您的计划输出中注意这一点-
-这是一个自适应计划
Oracle Database 12c中的自适应计划允许对执行计划进行运行时更改。通常会发生这种情况,因为统计信息对优化程序而言是谎言。 DB认为有5行,但是当它从索引或表中读取它们时,却发现50,000行。因此,为了解决这个问题,数据库将进行其他操作。
所以我的建议-
收集两个表上的统计信息:
BEGIN
dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'EMPLOYEES', estimate_percent => 100);
dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'DEPARTMENTS', estimate_percent => 100);
END;
然后,再次运行您的计划。除了这次,不要使用EXPLAIN PLAN FOR-请使用上面显示的第二个或第三个选项。
答案 1 :(得分:1)
您看到的是自适应计划的工件;您实际上在输出中看到了计划的两个版本。灰线表示未执行的计划版本。