问题描述
嗨,
当测试安全文件LOB段的NOCACHE选项并使用自动跟踪vs跟踪/TKPROF分析选择性能时,我看到了不同的结果。
Test Setup
Test 1: Select 500 rows with SET AUTOTRACE TRACEONLY
输出:
SELECT的后续运行显示类似的输出:
每个SELECT 显示1000 physical reads对于每次运行,这是我在配置LOB时所期望的NOCACHE
但是,当我执行相同的SELECT语句并跟踪它/tkprof时,即
TKPROF文件始终为磁盘读取显示0,例如
如果您可以解释为什么会发生这种情况,或者我对Autotrace/SQL Trace的2个指标的误解是什么,那就太好了。
谢谢
安德鲁
当测试安全文件LOB段的NOCACHE选项并使用自动跟踪vs跟踪/TKPROF分析选择性能时,我看到了不同的结果。
Test Setup
CREATE TABLE js_poc.clob_test_sf_nocache ( id NUMBER, json_data CLOB CHECK(json_data IS JSON) ) LOB(json_data) STORE AS SECUREFILE(NOCACHE);
INSERT INTO js_poc.clob_test_sf_nocache
SELECT level,'{"key":"This is a long string of text, repeat"}'
FROM dual
CONNECT BY level <= 1000;Test 1: Select 500 rows with SET AUTOTRACE TRACEONLY
sqlplus js_poc SET AUTOTRACE TRACEONLY SELECT json_data FROM clob_test_sf_nocache WHERE rownum <= 500;
输出:
Statistics
----------------------------------------------------------
31 recursive calls
7 db block gets
1014 consistent gets
1005 physical reads
1004 redo size
371998 bytes sent via SQL*Net to client
148424 bytes received via SQL*Net from client
1002 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
500 rows processedSELECT的后续运行显示类似的输出:
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
1003 consistent gets
1000 physical reads
0 redo size
371998 bytes sent via SQL*Net to client
148424 bytes received via SQL*Net from client
1002 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
500 rows processed每个SELECT 显示1000 physical reads对于每次运行,这是我在配置LOB时所期望的NOCACHE
但是,当我执行相同的SELECT语句并跟踪它/tkprof时,即
ALTER SESSION SET SQL_TRACE = TRUE; SELECT json_data FROM clob_test_sf_nocache WHERE rownum <= 500; ALTER SESSION SET SQL_TRACE = FALSE;
TKPROF文件始终为磁盘读取显示0,例如
call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 2 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 501 0.01 0.01 0 503 0 500 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 503 0.01 0.01 0 505 0 500
如果您可以解释为什么会发生这种情况,或者我对Autotrace/SQL Trace的2个指标的误解是什么,那就太好了。
谢谢
安德鲁
专家解答
这只是每个工具报告I/O的方式的细微差异。
当您查询LOB (足够大,不能与行内联存储) 时,“基” 查询将获取lob定位器 (只是一个指针),然后当您从表中获取行时,然后使用定位器执行额外的I/O以获取实际的lob数据。
set autotrace并不真正知道这一点-它只是在做一个增量,即
a-我的会话完成了多少个I/o?
b-运行我的查询
c-我的会话完成了多少个I/o?
d-报告差异
因此,它 “看到” 作为获取的一部分完成的I/O。所以让我们进一步探索一下。
没有LOB物理读取,因为它足够小,可以与行内联存储。
现在LOB是离线存储的,我们做了物理IO来获取每个lob
我添加了一个跟踪,通过
它以不同的方式代表活动...
您可以看到 “pr = 0” 数字-读取 * table * 不需要花费任何费用,但是在获取时,我们会报告 “disk” 计数2000年。但是,如果您低头查看等待事件,我们有500直接路径读取。如果我们对跟踪文件的详细信息进行了处理,则每次直接读取都会看到以下内容
因此,每个直接读取是针对4个块,因此给出了500*4 = 2000的总磁盘读取。
(这些测试都在19.8上完成)
当您查询LOB (足够大,不能与行内联存储) 时,“基” 查询将获取lob定位器 (只是一个指针),然后当您从表中获取行时,然后使用定位器执行额外的I/O以获取实际的lob数据。
set autotrace并不真正知道这一点-它只是在做一个增量,即
a-我的会话完成了多少个I/o?
b-运行我的查询
c-我的会话完成了多少个I/o?
d-报告差异
因此,它 “看到” 作为获取的一部分完成的I/O。所以让我们进一步探索一下。
SQL> CREATE TABLE clob_test_sf_nocache (
2 id NUMBER,
3 json_data CLOB CHECK(json_data IS JSON)
4 )
5 LOB(json_data) STORE AS SECUREFILE(NOCACHE);
Table created.
SQL>
SQL> INSERT INTO clob_test_sf_nocache
2 SELECT level,'{"key":"This is a long string of text, repeat"}'
3 FROM dual
4 CONNECT BY level <= 1000;
1000 rows created.
SQL>
SQL> commit;
Commit complete.
SQL>
SQL> set autotrace traceonly stat
SQL> SELECT json_data FROM clob_test_sf_nocache WHERE rownum <= 500;
500 rows selected.
Statistics
----------------------------------------------------------
29 recursive calls
7 db block gets
1038 consistent gets
1 physical reads
996 redo size
204998 bytes sent via SQL*Net to client
148424 bytes received via SQL*Net from client
502 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
500 rows processed
SQL> set autotrace off
没有LOB物理读取,因为它足够小,可以与行内联存储。
SQL> CREATE TABLE clob_test_sf_nocache (
2 id NUMBER,
3 json_data CLOB CHECK(json_data IS JSON)
4 )
5 LOB(json_data) STORE AS SECUREFILE(NOCACHE);
Table created.
SQL> INSERT INTO clob_test_sf_nocache
2 SELECT level,'{"key":"'||rpad('x',16000,'x')||'"}'
3 FROM dual
4 CONNECT BY level <= 1000;
1000 rows created.
SQL> commit;
Commit complete.
SQL> set autotrace traceonly stat
SQL> SELECT json_data FROM clob_test_sf_nocache WHERE rownum <= 500;
500 rows selected.
Statistics
----------------------------------------------------------
25 recursive calls
7 db block gets
1030 consistent gets
1001 physical reads
996 redo size
237998 bytes sent via SQL*Net to client
148424 bytes received via SQL*Net from client
502 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
500 rows processed
SQL> set autotrace off
现在LOB是离线存储的,我们做了物理IO来获取每个lob
我添加了一个跟踪,通过
SQL> alter session set events = '10046 trace name context forever, level 8'; Session altered. SQL> set feedback only SQL> SELECT json_data FROM clob_test_sf_nocache WHERE rownum <= 500; 500 rows selected.
它以不同的方式代表活动...
SELECT json_data
FROM
clob_test_sf_nocache WHERE rownum <= 500
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 4 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 501 0.13 0.14 2000 502 0 500
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 503 0.13 0.15 2000 506 0 500
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 107
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
500 500 500 COUNT STOPKEY (cr=502 pr=0 pw=0 time=2021 us starts=1)
500 500 500 TABLE ACCESS FULL CLOB_TEST_SF_NOCACHE (cr=502 pr=0 pw=0 time=2019 us starts=1 cost=4 size=67000 card=500)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 502 0.00 0.00
SQL*Net message from client 502 0.00 0.03
direct path read 502 0.00 0.04
SQL*Net more data to client 1501 0.00 0.03
您可以看到 “pr = 0” 数字-读取 * table * 不需要花费任何费用,但是在获取时,我们会报告 “disk” 计数2000年。但是,如果您低头查看等待事件,我们有500直接路径读取。如果我们对跟踪文件的详细信息进行了处理,则每次直接读取都会看到以下内容
WAIT #2345311765584: nam='direct path read' ela= 181 file number=64 first dba=61502 block cnt=4 obj#=123271 tim=2274769349559 WAIT #2345311765584: nam='direct path read' ela= 199 file number=64 first dba=61494 block cnt=4 obj#=123271 tim=2274769348517 WAIT #2345311765584: nam='direct path read' ela= 214 file number=64 first dba=61498 block cnt=4 obj#=123271 tim=2274769349045 WAIT #2345311765584: nam='direct path read' ela= 232 file number=64 first dba=61506 block cnt=4 obj#=123271 tim=2274769350116 WAIT #2345311765584: nam='direct path read' ela= 251 file number=64 first dba=61490 block cnt=4 obj#=123271 tim=2274769348005 WAIT #2345311765584: nam='direct path read' ela= 259 file number=64 first dba=61486 block cnt=4 obj#=123271 tim=2274769347431 ... ... ...
因此,每个直接读取是针对4个块,因此给出了500*4 = 2000的总磁盘读取。
(这些测试都在19.8上完成)
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




