无法理解 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。 执行计划的四个关键要素如下:

  1. Cardinality: 预估每个操作的行数
  2. 访问方法: 您的数据被访问。可能是 table 扫描或通过索引。
  3. Join 方法:可以是(排序合并、散列等)。它实际上是您 table 加入的类型。
  4. Join Order:执行联接的顺序 tables。

通过分解语句并研究上述元素,您可以更好地了解 Oracle 优化器如何选择最有效的计划。如果您想深入研究成本和基数,请查看 this post .嵌套行显示为执行查询而进行的操作。您可以看到您的加入及其费用。

嵌套循环:看看你的执行计划中的NESTED LOOPS: 顾名思义,对于第一个 table 中的每一行,Oracle 评估第二个中的所有行(实际上是内部 table)。连接少量数据时使用嵌套循环。第二个 table 也应该被有效地访问。

另一方面,

SORT MERGE JOINS 在较大的数据集中效率更高。

访问方法:一个有趣的信息是table的访问:在那里你可以看到是否使用索引进行访问。 如果有很大一部分数据要selected,没有相对索引,你可能会看到FULL TABLE SCAN。在这种情况下,来自 table 的所有行都被读取,不符合谓词条件的行被过滤掉。此操作可能会增加语句的成本。 INDEX RANGE SCANROWID 的 table 查找是扫描索引的成本和 ROWID 访问 table 的成本之和。一般来说,oracle 基本上从 WHERE 子句或通过索引扫描获取 rowid。 如果执行完全访问 table,这可能会导致您创建新索引。

查看您的解释计划,Oracle 优化器似乎避免了 FULL SCAN。这样做的代价是读取 table 的所有行。这表明查询速度较慢。

详细的文档可以看Oracle's Documentation