oracle执行计划,试图理解
oracle execution plan, trying to understand
EXPLAIN PLAN FOR
SELECT sightings.sighting_id, spotters.spotter_name,
sightings.sighting_date
FROM sightings
INNER JOIN spotters
ON sightings.spotter_id = spotters.spotter_id
WHERE sightings.spotter_id = 1255;
SELECT plan_table_output
FROM table(dbms_xplan.display('plan_table',null,'basic'));
id Operation Name
0 select statement
1 nested loops
2 table access by index rowid spotters
3 index unique scan pk_spotter_ID
4 table access full sightings
我想了解这里到底发生了什么,这听起来对吗:
首先对 select 语句求值,不在 select 列表中的属性在输出中被忽略
嵌套循环然后在 spotters.spotters_id = sightings.spotter_id
上计算内部连接
Table 通过索引 rowid 访问检索具有步骤 3 从观察者返回的 rowid 的行 table
索引唯一扫描,在PK_SPOTTER_ID索引中扫描spotter_id并在观察者table
中找到关联行的rowids
Table 访问权限已满,然后完全扫描目击事件,直到找到 sighting_id = 1255
注意:此答案指的是问题的原始版本。
Oracle 正在完整读取这两个表。
它根据 join
键对每个表进行哈希处理 -- "re-ordering" 表因此相似的键彼此靠近。
正在连接。
然后进行最终的计算 select
并将结果返回给用户。
步骤基本正确,但应该是自下而上。
投影(选择相关列)最好在扫描阶段尽早完成。
索引操作是SEEK(你不是扫描整个索引)
这就是按照正确的顺序非正式地发生的事情:
-- The index pk_spotter_id is scanned for at most one row that satisfies spotter_id = 1255
3 index unique scan pk_spotter_ID
-- The spotter_name column is fetched from the table spotters for the previously found row
2 table access by index rowid spotters
-- A nested loop is run for each (i.e. at most one) of the previously found rows
1 nested loops
-- That nested loop will scan the entire sightings table for rows that match the join
-- predicate sightings.spotter_id = spotters.spotter_id
4 table access full sightings
-- That'll be it for your select statement
0 select statement
一般情况下(有很多例外),可以读取Oracle执行计划
- 自下而上
- 第一个兄弟姐妹优先
这意味着你沿着树向下走直到找到第一个叶操作(例如#3),它将被执行"first",它的结果被提供给父节点(例如#2),然后所有兄弟姐妹自上而下执行,所有兄弟姐妹的结果也被馈送到父级,然后父级结果被馈送到祖父级(例如#1),直到到达顶部操作。
这是对所发生情况的非常非正式的解释。请注意,一旦语句变得更加复杂,这些规则将有许多例外情况。
EXPLAIN PLAN FOR
SELECT sightings.sighting_id, spotters.spotter_name,
sightings.sighting_date
FROM sightings
INNER JOIN spotters
ON sightings.spotter_id = spotters.spotter_id
WHERE sightings.spotter_id = 1255;
SELECT plan_table_output
FROM table(dbms_xplan.display('plan_table',null,'basic'));
id Operation Name
0 select statement
1 nested loops
2 table access by index rowid spotters
3 index unique scan pk_spotter_ID
4 table access full sightings
我想了解这里到底发生了什么,这听起来对吗:
首先对 select 语句求值,不在 select 列表中的属性在输出中被忽略
嵌套循环然后在 spotters.spotters_id = sightings.spotter_id
上计算内部连接
Table 通过索引 rowid 访问检索具有步骤 3 从观察者返回的 rowid 的行 table
索引唯一扫描,在PK_SPOTTER_ID索引中扫描spotter_id并在观察者table
中找到关联行的rowids
Table 访问权限已满,然后完全扫描目击事件,直到找到 sighting_id = 1255
注意:此答案指的是问题的原始版本。
Oracle 正在完整读取这两个表。
它根据 join
键对每个表进行哈希处理 -- "re-ordering" 表因此相似的键彼此靠近。
正在连接。
然后进行最终的计算 select
并将结果返回给用户。
步骤基本正确,但应该是自下而上。 投影(选择相关列)最好在扫描阶段尽早完成。 索引操作是SEEK(你不是扫描整个索引)
这就是按照正确的顺序非正式地发生的事情:
-- The index pk_spotter_id is scanned for at most one row that satisfies spotter_id = 1255
3 index unique scan pk_spotter_ID
-- The spotter_name column is fetched from the table spotters for the previously found row
2 table access by index rowid spotters
-- A nested loop is run for each (i.e. at most one) of the previously found rows
1 nested loops
-- That nested loop will scan the entire sightings table for rows that match the join
-- predicate sightings.spotter_id = spotters.spotter_id
4 table access full sightings
-- That'll be it for your select statement
0 select statement
一般情况下(有很多例外),可以读取Oracle执行计划
- 自下而上
- 第一个兄弟姐妹优先
这意味着你沿着树向下走直到找到第一个叶操作(例如#3),它将被执行"first",它的结果被提供给父节点(例如#2),然后所有兄弟姐妹自上而下执行,所有兄弟姐妹的结果也被馈送到父级,然后父级结果被馈送到祖父级(例如#1),直到到达顶部操作。
这是对所发生情况的非常非正式的解释。请注意,一旦语句变得更加复杂,这些规则将有许多例外情况。