无法理解 SQL 解释计划
Unable to understand SQL Explain Plan
我目前正在进行查询优化,这需要很长时间 运行。当我用谷歌搜索时,我发现我们可以使用 sql Explain Plan 检查查询性能,下面是我为我的查询得到的计划,但我无法理解到底是什么它说的是什么。!
SELECT STATEMENT ALL_ROWS Cost: 13 Bytes: 187 Cardinality: 1
15 NESTED LOOPS Cost: 13 Bytes: 187 Cardinality: 1
12 NESTED LOOPS Cost: 11 Bytes: 163 Cardinality: 1
9 NESTED LOOPS Cost: 10 Bytes: 146 Cardinality: 1
6 MERGE JOIN CARTESIAN Cost: 8 Bytes: 59 Cardinality: 1
2 TABLE ACCESS BY INDEX ROWID TABLE QUAD.GROUP_ Cost: 4 Bytes: 27 Cardinality: 1
1 INDEX SKIP SCAN INDEX (UNIQUE) QUAD.IX_5BDDB872 Cost: 3 Cardinality: 1
5 BUFFER SORT Cost: 4 Bytes: 32 Cardinality: 1
4 TABLE ACCESS BY INDEX ROWID TABLE QUAD.USER_ Cost: 4 Bytes: 32 Cardinality: 1
3 INDEX SKIP SCAN INDEX (UNIQUE) QUAD.IX_C5806019 Cost: 3 Cardinality: 1
8 TABLE ACCESS BY INDEX ROWID TABLE QUAD.IGIMAGE Cost: 2 Bytes: 87 Cardinality: 1
7 INDEX RANGE SCAN INDEX QUAD.IX_BE79E1E1 Cost: 1 Cardinality: 1
11 TABLE ACCESS BY INDEX ROWID TABLE QUAD.IGFOLDER Cost: 1 Bytes: 17 Cardinality: 1
10 INDEX UNIQUE SCAN INDEX (UNIQUE) QUAD.SYS_C00117581 Cost: 0 Cardinality: 1
14 TABLE ACCESS BY INDEX ROWID TABLE QUAD.IMAGE Cost: 2 Bytes: 24 Cardinality: 1
13 INDEX UNIQUE SCAN INDEX (UNIQUE) QUAD.SYS_C00117585 Cost: 1 Cardinality: 1
请告诉我它是如何工作的,这个输出有什么问题吗?
select ig.largeimageid, ig.groupId, ig.createDate, ig.modifiedDate, ig.folderId, ig.name, ig.imageid,
ig.description, im.type_, im.height, im.width, im.size_,
g.name groupname, u.screenname cecuserid, u.firstname, u.lastname,
fo.name folderName, fo.description folderDesc
from quad.igimage ig,quad.image im, quad.group_ g, quad.user_ u, quad.igfolder fo
where ig.groupid= g.groupid
and u.userid = ig.userid
and fo.folderid=ig.folderid
and ig.largeimageid= im.imageid
and u.screenname='xyz'
and g.friendlyurl = '/xyz';
Oracle 使用Optimizer 来确定最有效的执行计划。请记住,它根据 统计信息 做出决定。这意味着必须有足够的统计数据。
执行计划显示执行语句的详细步骤。因此,第一行的 SELECT
是您的实际查询。这个 select 的成本是 13 这实际上是嵌套操作的成本。
您查询的基数是 1。
执行计划的四个关键要素如下:
- Cardinality: 预估每个操作的行数
- 访问方法: 您的数据被访问。可能是 table 扫描或通过索引。
- Join 方法:可以是(排序合并、散列等)。它实际上是您 table 加入的类型。
- Join Order:执行联接的顺序 tables。
通过分解语句并研究上述元素,您可以更好地了解 Oracle 优化器如何选择最有效的计划。如果您想深入研究成本和基数,请查看 this post
.嵌套行显示为执行查询而进行的操作。您可以看到您的加入及其费用。
嵌套循环:看看你的执行计划中的NESTED LOOPS
:
顾名思义,对于第一个 table 中的每一行,Oracle 评估第二个中的所有行(实际上是内部 table)。连接少量数据时使用嵌套循环。第二个 table 也应该被有效地访问。
另一方面,SORT MERGE JOINS
在较大的数据集中效率更高。
访问方法:一个有趣的信息是table的访问:在那里你可以看到是否使用索引进行访问。
如果有很大一部分数据要selected,没有相对索引,你可能会看到FULL TABLE SCAN
。在这种情况下,来自 table 的所有行都被读取,不符合谓词条件的行被过滤掉。此操作可能会增加语句的成本。
INDEX RANGE SCAN
和 ROWID
的 table 查找是扫描索引的成本和 ROWID
访问 table 的成本之和。一般来说,oracle 基本上从 WHERE
子句或通过索引扫描获取 rowid。
如果执行完全访问 table,这可能会导致您创建新索引。
查看您的解释计划,Oracle 优化器似乎避免了 FULL SCAN
。这样做的代价是读取 table 的所有行。这表明查询速度较慢。
详细的文档可以看Oracle's Documentation
我目前正在进行查询优化,这需要很长时间 运行。当我用谷歌搜索时,我发现我们可以使用 sql Explain Plan 检查查询性能,下面是我为我的查询得到的计划,但我无法理解到底是什么它说的是什么。!
SELECT STATEMENT ALL_ROWS Cost: 13 Bytes: 187 Cardinality: 1
15 NESTED LOOPS Cost: 13 Bytes: 187 Cardinality: 1
12 NESTED LOOPS Cost: 11 Bytes: 163 Cardinality: 1
9 NESTED LOOPS Cost: 10 Bytes: 146 Cardinality: 1
6 MERGE JOIN CARTESIAN Cost: 8 Bytes: 59 Cardinality: 1
2 TABLE ACCESS BY INDEX ROWID TABLE QUAD.GROUP_ Cost: 4 Bytes: 27 Cardinality: 1
1 INDEX SKIP SCAN INDEX (UNIQUE) QUAD.IX_5BDDB872 Cost: 3 Cardinality: 1
5 BUFFER SORT Cost: 4 Bytes: 32 Cardinality: 1
4 TABLE ACCESS BY INDEX ROWID TABLE QUAD.USER_ Cost: 4 Bytes: 32 Cardinality: 1
3 INDEX SKIP SCAN INDEX (UNIQUE) QUAD.IX_C5806019 Cost: 3 Cardinality: 1
8 TABLE ACCESS BY INDEX ROWID TABLE QUAD.IGIMAGE Cost: 2 Bytes: 87 Cardinality: 1
7 INDEX RANGE SCAN INDEX QUAD.IX_BE79E1E1 Cost: 1 Cardinality: 1
11 TABLE ACCESS BY INDEX ROWID TABLE QUAD.IGFOLDER Cost: 1 Bytes: 17 Cardinality: 1
10 INDEX UNIQUE SCAN INDEX (UNIQUE) QUAD.SYS_C00117581 Cost: 0 Cardinality: 1
14 TABLE ACCESS BY INDEX ROWID TABLE QUAD.IMAGE Cost: 2 Bytes: 24 Cardinality: 1
13 INDEX UNIQUE SCAN INDEX (UNIQUE) QUAD.SYS_C00117585 Cost: 1 Cardinality: 1
请告诉我它是如何工作的,这个输出有什么问题吗?
select ig.largeimageid, ig.groupId, ig.createDate, ig.modifiedDate, ig.folderId, ig.name, ig.imageid,
ig.description, im.type_, im.height, im.width, im.size_,
g.name groupname, u.screenname cecuserid, u.firstname, u.lastname,
fo.name folderName, fo.description folderDesc
from quad.igimage ig,quad.image im, quad.group_ g, quad.user_ u, quad.igfolder fo
where ig.groupid= g.groupid
and u.userid = ig.userid
and fo.folderid=ig.folderid
and ig.largeimageid= im.imageid
and u.screenname='xyz'
and g.friendlyurl = '/xyz';
Oracle 使用Optimizer 来确定最有效的执行计划。请记住,它根据 统计信息 做出决定。这意味着必须有足够的统计数据。
执行计划显示执行语句的详细步骤。因此,第一行的 SELECT
是您的实际查询。这个 select 的成本是 13 这实际上是嵌套操作的成本。
您查询的基数是 1。
执行计划的四个关键要素如下:
- Cardinality: 预估每个操作的行数
- 访问方法: 您的数据被访问。可能是 table 扫描或通过索引。
- Join 方法:可以是(排序合并、散列等)。它实际上是您 table 加入的类型。
- Join Order:执行联接的顺序 tables。
通过分解语句并研究上述元素,您可以更好地了解 Oracle 优化器如何选择最有效的计划。如果您想深入研究成本和基数,请查看 this post .嵌套行显示为执行查询而进行的操作。您可以看到您的加入及其费用。
嵌套循环:看看你的执行计划中的NESTED LOOPS
:
顾名思义,对于第一个 table 中的每一行,Oracle 评估第二个中的所有行(实际上是内部 table)。连接少量数据时使用嵌套循环。第二个 table 也应该被有效地访问。
SORT MERGE JOINS
在较大的数据集中效率更高。
访问方法:一个有趣的信息是table的访问:在那里你可以看到是否使用索引进行访问。
如果有很大一部分数据要selected,没有相对索引,你可能会看到FULL TABLE SCAN
。在这种情况下,来自 table 的所有行都被读取,不符合谓词条件的行被过滤掉。此操作可能会增加语句的成本。
INDEX RANGE SCAN
和 ROWID
的 table 查找是扫描索引的成本和 ROWID
访问 table 的成本之和。一般来说,oracle 基本上从 WHERE
子句或通过索引扫描获取 rowid。
如果执行完全访问 table,这可能会导致您创建新索引。
查看您的解释计划,Oracle 优化器似乎避免了 FULL SCAN
。这样做的代价是读取 table 的所有行。这表明查询速度较慢。
详细的文档可以看Oracle's Documentation