为什么在我的 TKPROF 输出中有一个简单的 select 语句的当前块读取?为什么一个查询中有两个解析?

Why there are current block reads in my TKPROF output on a simple select statement? Why there are two parses in one query?

在下面的查询中,我在 Oracle 的查询中使用了示例 SH 模式。当我获得该查询的 TKPROF 输出时,我看到有一些当前块读取。但据我所知,当前块读取发生在该块对其进行更改时。但是我没有执行任何更新或其他操作。我刚刚执行了那个查询。

那么,为什么有 28 个当前模式块读取?

下一个问题,在执行计划统计中,有些starts值为0,是不是表示这一步没有执行?但是当我检查自动跟踪输出时,似乎这些步骤也被执行了。 (例如,索引唯一扫描 customers_pk 有 starts = 0)。那么这一步执行了吗?如果是,为什么这里写0?

最后一个问题,为什么一个查询中同时存在硬解析和软解析(两次解析)?

提前致谢。

select s.prod_id, p.prod_name, s.cust_id, c.cust_first_name 
from
 sh.sales s, sh.products p, sh.customers c where s.prod_id = p.prod_id and 
  s.cust_id = c.cust_id and s.amount_sold > 1500


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.03       0.03          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch      542      0.32       0.72          0       3607         28        8114
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total      544      0.35       0.76          0       3607         28        8114

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
      8114       8114       8114  HASH JOIN  (cr=3607 pr=0 pw=0 time=450527 us starts=1 cost=859 size=469504 card=8384)
      8114       8114       8114   NESTED LOOPS  (cr=1643 pr=0 pw=0 time=253284 us starts=1 cost=859 size=469504 card=8384)
      8114       8114       8114    NESTED LOOPS  (cr=1643 pr=0 pw=0 time=251761 us starts=1)
      8114       8114       8114     STATISTICS COLLECTOR  (cr=1643 pr=0 pw=0 time=250365 us starts=1)
      8114       8114       8114      HASH JOIN  (cr=1643 pr=0 pw=0 time=250044 us starts=1 cost=454 size=368896 card=8384)
        72         72         72       NESTED LOOPS  (cr=8 pr=0 pw=0 time=863 us starts=1 cost=454 size=368896 card=8384)
        72         72         72        STATISTICS COLLECTOR  (cr=8 pr=0 pw=0 time=790 us starts=1)
        72         72         72         TABLE ACCESS FULL PRODUCTS (cr=8 pr=0 pw=0 time=691 us starts=1 cost=3 size=2160 card=72)
         0          0          0        PARTITION RANGE ALL PARTITION: 1 28 (cr=0 pr=0 pw=0 time=0 us starts=0 cost=451 size=1624 card=116)
         0          0          0         TABLE ACCESS BY LOCAL INDEX ROWID BATCHED SALES PARTITION: 1 28 (cr=0 pr=0 pw=0 time=0 us starts=0 cost=451 size=1624 card=116)
         0          0          0          BITMAP CONVERSION TO ROWIDS (cr=0 pr=0 pw=0 time=0 us starts=0)
         0          0          0           BITMAP INDEX SINGLE VALUE SALES_PROD_BIX PARTITION: 1 28 (cr=0 pr=0 pw=0 time=0 us starts=0)(object id 101439)
      8114       8114       8114       PARTITION RANGE ALL PARTITION: 1 28 (cr=1635 pr=0 pw=0 time=248277 us starts=1 cost=451 size=117376 card=8384)
      8114       8114       8114        TABLE ACCESS FULL SALES PARTITION: 1 28 (cr=1635 pr=0 pw=0 time=208294 us starts=28 cost=451 size=117376 card=8384)
         0          0          0     INDEX UNIQUE SCAN CUSTOMERS_PK (cr=0 pr=0 pw=0 time=0 us starts=0)(object id 101249)
         0          0          0    TABLE ACCESS BY INDEX ROWID CUSTOMERS (cr=0 pr=0 pw=0 time=0 us starts=0 cost=405 size=12 card=1)
     55500      55500      55500   TABLE ACCESS FULL CUSTOMERS (cr=1964 pr=0 pw=0 time=120870 us starts=1 cost=405 size=666000 card=55500)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  PGA memory operation                           35        0.00          0.00
  Disk file operations I/O                        1        0.00          0.00
  SQL*Net message to client                     542        0.00          0.00
  SQL*Net message from client                   542       41.10         57.47
********************************************************************************

我们通常不会在这里收到很多 tuning/optimization 问题,但我会尽力回答这个问题。

  1. 当前块获取可能表示块上的更改 (DML),但并非总是如此。它们也会在您进行全面扫描时出现,因为 the segment headers have to be read in "current mode" in order to figure out how to scan the table.

  2. 是的,"starts" 为 0 表示未执行该步骤。您会注意到这些步骤也有 0 行。这些步骤仍然是计划的一部分,因为如果任何行 did 符合这些条件,则需要执行这些步骤。但在这种情况下,它们没有被使用。

  3. 没有两次解析 - 您只 运行 语句一次,所以它只被解析一次。这就是 Parse count 1 的意思。这是一个硬解析,因为您的第一个 运行 查询始终是一个硬解析。您可以在它说 "Misses in library cache during parse: 1" 的地方看到它。它检查这个确切的查询之前是否是 运行 而现在没有;因此很难解析。如果您再次 运行 这个完全相同的查询,它会在库缓存中找到它,这将是一个软解析。