无法理解SQL解释计划

时间:2015-07-17 09:22:04

标签: sql oracle sql-execution-plan

我目前正在进行查询优化,这需要很长时间才能运行。当我用谷歌搜索它时,我发现我们可以使用sql 解释计划检查查询性能,下面是我查询的计划,但我无法理解它究竟是什么。!

 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';

1 个答案:

答案 0 :(得分:4)

Oracle使用Optimizer来确定最有效的执行计划。请记住,它会根据统计信息做出决策。这意味着必须有足够的统计数据。 执行计划显示执行语句的详细步骤。因此,第一行的SELECT是您的实际查询。此选择的成本为13,实际上是嵌套操作的成本。 您查询的基数为1。 执行计划的四个关键要素如下:

  1. 基数:估算每项操作的行数。
  2. 访问方式:访问您的数据。可以是表扫描或通过索引。
  3. 加入方法:可以是(排序合并,哈希等)。它实际上是表连接的类型。
  4. 加入订单:对表执行联接的顺序。
  5. 通过分解声明并调查上述元素,您可以更好地了解Oracle优化器如何选择最有效的计划。如果您想深入研究成本和基数,请查看this post 。嵌套行显示为执行查询而执行的操作。您可以看到您的联接及其费用。

    嵌套循环:在执行计划中查看NESTED LOOPS: 正如名称所声明的那样,对于第一个表中的每一行,Oracle都会评估第二个行中的所有行(实际上是内部表)。加入少量数据时使用嵌套循环。还应该有效地访问第二个表。

    另一方面,

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

    访问方法:一个有趣的信息是表的访问:在那里你可以看到索引是否用于访问。 如果要选择大部分数据并且没有相对索引,则可能会看到FULL TABLE SCAN。在这种情况下,将读取表中的所有行,并过滤掉不符合谓词标准的行。此操作可能会增加语句的成本。 INDEX RANGE SCANROWID的表查找是扫描索引的成本和ROWID访问表的成本的总和。通常,oracle基本上从WHERE子句或通过索引扫描获取rowid。 如果执行完整访问表,这可能会导致您创建新索引。

    查看您的解释计划,似乎Oracle优化器避免使用FULL SCAN。这样做的成本是读取表格的所有行。这表明查询速度缓慢。

    有关详细文档,请查看Oracle's Documentation