SQL Developer vs Explain Plan for command 中的不同解释计划
Different Explain Plans in SQL Developer vs Explain Plan for command
当我得到以下查询的解释计划时,我看到 table 都进行了完整的 table 扫描。
SELECT *
FROM employees e,
departments d
WHERE e.employee_id = d.manager_id;
这是我用解释计划命令得到的解释计划。 by EXPLAIN PLAN FOR command
https://i.hizliresim.com/JZdB2o.jpg
https://hizliresim.com/JZdB2o https://pasteboard.co/HO9ARcl.jpg
但是,如果我与 SQL 开发人员一起获得相同查询的解释计划,我会看到一个明显不同的解释计划。
特别是,它在底部写 table 访问完全,但在它上面,它写 table 按索引 rowid 访问。
这是我从 SQL 开发人员那里得到的解释计划。 by SQL Developer Explain Plan button
https://i.hizliresim.com/DYoYbv.jpg
https://hizliresim.com/DYoYbv https://pasteboard.co/HO9BxfA.jpg
我的问题是,任何人都可以逐步解释 SQL 开发人员 的 解释计划吗?为什么 SQL 开发人员和解释计划命令生成不同的解释计划?
提前致谢。
在 SQL Developer 中有几种不同的方法可以获取查询计划。
解释计划
缓存计划
DBMS_XPLAN
您使用的是哪种方法?您对图片进行了裁剪,以至于我们无法判断这是来自 V$SQL_PLAN 的缓存计划还是解释计划。
现在,进入问题的关键 - 不要使用解释计划。它可能不可靠。它向您展示了一个可能 运行 的计划 - 它没有向您展示已经或将要使用的实际计划。
还要在您的计划输出中注意这一点 -
-- this is an adaptive plan
Oracle Database 12c 中的自适应计划允许 运行 对执行计划进行时间更改。它通常发生是因为统计数据对优化器说谎。数据库认为有 5 行,但是当它从索引或 table 中读取它们时,它发现了 50,000 行。所以数据库走了,管它呢,我们要做点别的事情。
所以我的建议 -
收集关于你的两个 table 的统计数据:
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 - 使用上面显示的第二个或第三个选项。
您看到的是自适应计划的产物;您实际上在输出中看到了计划的两个版本。灰色线条是未执行的计划版本。
当我得到以下查询的解释计划时,我看到 table 都进行了完整的 table 扫描。
SELECT *
FROM employees e,
departments d
WHERE e.employee_id = d.manager_id;
这是我用解释计划命令得到的解释计划。 by EXPLAIN PLAN FOR command
https://i.hizliresim.com/JZdB2o.jpg https://hizliresim.com/JZdB2o https://pasteboard.co/HO9ARcl.jpg
但是,如果我与 SQL 开发人员一起获得相同查询的解释计划,我会看到一个明显不同的解释计划。 特别是,它在底部写 table 访问完全,但在它上面,它写 table 按索引 rowid 访问。
这是我从 SQL 开发人员那里得到的解释计划。 by SQL Developer Explain Plan button
https://i.hizliresim.com/DYoYbv.jpg https://hizliresim.com/DYoYbv https://pasteboard.co/HO9BxfA.jpg
我的问题是,任何人都可以逐步解释 SQL 开发人员 的 解释计划吗?为什么 SQL 开发人员和解释计划命令生成不同的解释计划?
提前致谢。
在 SQL Developer 中有几种不同的方法可以获取查询计划。
解释计划
缓存计划
DBMS_XPLAN
您使用的是哪种方法?您对图片进行了裁剪,以至于我们无法判断这是来自 V$SQL_PLAN 的缓存计划还是解释计划。
现在,进入问题的关键 - 不要使用解释计划。它可能不可靠。它向您展示了一个可能 运行 的计划 - 它没有向您展示已经或将要使用的实际计划。
还要在您的计划输出中注意这一点 -
-- this is an adaptive plan
Oracle Database 12c 中的自适应计划允许 运行 对执行计划进行时间更改。它通常发生是因为统计数据对优化器说谎。数据库认为有 5 行,但是当它从索引或 table 中读取它们时,它发现了 50,000 行。所以数据库走了,管它呢,我们要做点别的事情。
所以我的建议 -
收集关于你的两个 table 的统计数据:
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 - 使用上面显示的第二个或第三个选项。
您看到的是自适应计划的产物;您实际上在输出中看到了计划的两个版本。灰色线条是未执行的计划版本。