ITPub博客

首页 > 数据库 > Oracle > [20240410]奇怪的逻辑读.txt

[20240410]奇怪的逻辑读.txt

原创 Oracle 作者:lfree 时间:2024-04-22 20:41:34 0 删除 编辑

[20240410]奇怪的逻辑读.txt

--//生产系统优化遇到奇怪的执行情况,搞不懂为什么?探究看看.

1.环境:
SYS@127.0.0.1:9014/ywdb> @ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

2.问题分析:
SYS@127.0.0.1:9014/ywdb> @ fms 5 10 &day
FORCE_MATCHING_SIGNATURE SQL_ID_COUNT TOTAL_SECONDS
------------------------ ------------ -------------
     8680396602758190538         1400          1722
    13026426528625086727          774          1169
     6490285911540139840          277           320
    12120531484079936454          275           289
     8968795636694904691          148           252
    16302384038956377077          200           225
    15582081887848190096          134           184
    13723358513528852507           92           160
     7809763007758332172          143           159
    10224702229797097847           45            67
10 rows selected.

--//fms脚本用来查询gv$active_session_history记录FORCE_MATCHING_SIGNATURE相同sql_id不同的sql语句.

SYS@127.0.0.1:9014/ywdb> @ ffms 8680396602758190538 10
C200
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
select a.ksdm,a.jgid,a.ksmc,b.act from ms_ghks a,(select count(1) as act,ksdm,jgid from (SELECT MS_YYHY.HYID, to_char(MS_YYHY.GZRQ,'yyyymmdd')  GZRQ ,MS_YYHY.YYSD,  MS_GHKS.KSMC, MS_YYHY.KSDM, GY_YGDM
.YGXM, MS_YYHY.YSDM, MS_YYHY.YYBZ,MS_MZGHF.GHF,MS_MZGHF.ZLF,MS_GHKS.JGID  FROM MS_YYHY,MS_GHKS,GY_YGDM,MS_YSKS,MS_MZGHF
                        WHERE MS_YYHY.KSDM = MS_GHKS.KSDM AND MS_YYHY.YSDM = GY_YGDM.YGDM AND MS_YSKS.Mzks = MS_YYHY.KSDM AND MS_YSKS.YSDM = GY_YGDM.YGDM AND MS_YSKS.FYXH = MS_MZGHF.FYXH AND MS_YYHY.T
GBZ = 0 AND MS_YYHY.YYBZ = 0 AND MS_YYHY.NWBZ = 1 AND MS_YYHY.GZRQ = to_date('20240413','yyyymmdd') And MS_YYHY.YSDM='5729'AND MS_GHKS.KSDM =273) group by ksdm,jgid) b where a.ksdm=b.ksdm and a.jgid=b
.jgid and a.ksdm =273 order by a.jgid

time unit : microsecond

SQL_ID        CHILD_NUMBER    INST_ID FIRST_LOAD_TIME     BUFFER_GETS EXECUTIONS ROWS_PROCESSED ELAPSED_TIME AVG_ELA_TIME PLAN_HASH_VALUE LIOS_PER_EXEC
------------- ------------ ---------- ------------------- ----------- ---------- -------------- ------------ ------------ --------------- -------------
a2d7vmm3wtgvc            0          2 2024-04-10/10:05:14         231          1              0        61472        61472      1874477375           231
7f7kuqqd1z2zp            0          2 2024-04-10/10:05:14         231          1              0        60417        60417      1874477375           231
839152ckx6c48            0          2 2024-04-10/10:05:14         231          1              0        63390        63390      1874477375           231
5ka1w8x55q2yd            0          2 2024-04-10/10:05:13         231          1              0        66518        66518      1874477375           231
9v26k2ftumjqn            0          1 2024-04-10/10:05:13         231          1              0        64188        64188      1874477375           231
87r0x9fna7frj            0          2 2024-04-10/10:05:13         231          1              0        60880        60880      1874477375           231
gwtzpbubyaua2            0          2 2024-04-10/10:05:13         231          1              0        89278        89278      1874477375           231
765qr5schjdwh            0          2 2024-04-10/10:04:51         231          1              0        78078        78078      1874477375           231
86b5n8jdb72n0            0          1 2024-04-10/10:04:44         231          1              0        71647        71647      1874477375           231
6tc2gf72wz9jx            0          1 2024-04-10/10:04:44         231          1              0        49302        49302      1874477375           231

10 rows selected.
--//ffms.sql脚本用来查询gv$sql看看FORCE_MATCHING_SIGNATURE=8680396602758190538有那些,参数2显示数量.前面查询的sql语句仅仅
--//显示1条作为参考.
--//你可以发现1个现象,ROWS_PROCESSED=0.逻辑读231.并且执行次数基本都是1,扩大查询范围也是一样,而我手工执行逻辑读都是1(即使
--//我修改sql语句,做硬解析):
Plan hash value: 1874477375
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name                | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |                     |      1 |        |       |     7 (100)|          |      0 |00:00:00.01 |       1 |       |       |          |
|   1 |  NESTED LOOPS                         |                     |      1 |      1 |    68 |     7  (15)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|   2 |   VIEW                                |                     |      1 |      1 |    28 |     6  (17)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|   3 |    HASH GROUP BY                      |                     |      1 |      1 |    44 |     6  (17)| 00:00:01 |      0 |00:00:00.01 |       1 |   983K|   983K|          |
|   4 |     NESTED LOOPS                      |                     |      1 |      1 |    44 |     6  (17)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|   5 |      NESTED LOOPS                     |                     |      1 |      1 |    41 |     6  (17)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|   6 |       NESTED LOOPS                    |                     |      1 |      1 |    29 |     5  (20)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|   7 |        VIEW                           | VW_GBF_32           |      1 |      1 |    24 |     5  (20)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|   8 |         HASH GROUP BY                 |                     |      1 |      1 |    46 |     5  (20)| 00:00:01 |      0 |00:00:00.01 |       1 |   964K|   964K|          |
|   9 |          NESTED LOOPS                 |                     |      1 |      1 |    46 |     4   (0)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|  10 |           NESTED LOOPS                |                     |      1 |      2 |    46 |     4   (0)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|  11 |            TABLE ACCESS BY INDEX ROWID| MS_GHKS             |      1 |      1 |    20 |     1   (0)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|* 12 |             INDEX RANGE SCAN          | I_MS_GHKS_KSDM      |      1 |      1 |       |     1   (0)| 00:00:01 |      0 |00:00:00.01 |       1 |       |       |          |
|* 13 |            INDEX RANGE SCAN           | I_MS_YYHY_GZRQ_YSDM |      0 |      2 |       |     2   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |       |       |          |
|* 14 |           TABLE ACCESS BY INDEX ROWID | MS_YYHY             |      0 |      1 |    26 |     3   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |       |       |          |
|* 15 |        INDEX UNIQUE SCAN              | PK_GY_YGDM          |      0 |      1 |     5 |     0   (0)|          |      0 |00:00:00.01 |       0 |       |       |          |
|  16 |       TABLE ACCESS BY INDEX ROWID     | MS_YSKS             |      0 |      1 |    12 |     1   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |       |       |          |
|* 17 |        INDEX UNIQUE SCAN              | I_MS_YSKS_MZKS_YSDM |      0 |      1 |       |     0   (0)|          |      0 |00:00:00.01 |       0 |       |       |          |
|* 18 |      INDEX UNIQUE SCAN                | PK_MS_MZGHF         |      0 |      1 |     3 |     0   (0)|          |      0 |00:00:00.01 |       0 |       |       |          |
|* 19 |   TABLE ACCESS BY INDEX ROWID         | MS_GHKS             |      0 |      1 |    40 |     1   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |       |       |          |
|* 20 |    INDEX RANGE SCAN                   | I_MS_GHKS_KSDM      |      0 |      1 |       |     0   (0)|          |      0 |00:00:00.01 |       0 |       |       |          |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--//逻辑读是1.难道第1次执行许多递归的逻辑读都要计入该语句中吗?
--//我使用set autotrace traceonly跟踪.适当修改sql语句,修改一个字符从大写变成小写,这样重新做1次硬分析.
SYS@127.0.0.1:9014/ywdb> @ gzbpf991tzmtr.sql9_0
PL/SQL procedure successfully completed.
Session altered.
Session altered.
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 1874477375
-------------------------------------------------------------------------------------------------------------
| Id  | Operation                             | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |                     |     1 |    68 |     7  (15)| 00:00:01 |
|   1 |  NESTED LOOPS                         |                     |     1 |    68 |     7  (15)| 00:00:01 |
|   2 |   VIEW                                |                     |     1 |    28 |     6  (17)| 00:00:01 |
|   3 |    HASH GROUP BY                      |                     |     1 |    44 |     6  (17)| 00:00:01 |
|   4 |     NESTED LOOPS                      |                     |     1 |    44 |     6  (17)| 00:00:01 |
|   5 |      NESTED LOOPS                     |                     |     1 |    41 |     6  (17)| 00:00:01 |
|   6 |       NESTED LOOPS                    |                     |     1 |    29 |     5  (20)| 00:00:01 |
|   7 |        VIEW                           | VW_GBF_32           |     1 |    24 |     5  (20)| 00:00:01 |
|   8 |         HASH GROUP BY                 |                     |     1 |    46 |     5  (20)| 00:00:01 |
|   9 |          NESTED LOOPS                 |                     |     1 |    46 |     4   (0)| 00:00:01 |
|  10 |           NESTED LOOPS                |                     |     2 |    46 |     4   (0)| 00:00:01 |
|  11 |            TABLE ACCESS BY INDEX ROWID| MS_GHKS             |     1 |    20 |     1   (0)| 00:00:01 |
|* 12 |             INDEX RANGE SCAN          | I_MS_GHKS_KSDM      |     1 |       |     1   (0)| 00:00:01 |
|* 13 |            INDEX RANGE SCAN           | I_MS_YYHY_GZRQ_YSDM |     2 |       |     2   (0)| 00:00:01 |
|* 14 |           TABLE ACCESS BY INDEX ROWID | MS_YYHY             |     1 |    26 |     3   (0)| 00:00:01 |
|* 15 |        INDEX UNIQUE SCAN              | PK_GY_YGDM          |     1 |     5 |     0   (0)| 00:00:01 |
|  16 |       TABLE ACCESS BY INDEX ROWID     | MS_YSKS             |     1 |    12 |     1   (0)| 00:00:01 |
|* 17 |        INDEX UNIQUE SCAN              | I_MS_YSKS_MZKS_YSDM |     1 |       |     0   (0)| 00:00:01 |
|* 18 |      INDEX UNIQUE SCAN                | PK_MS_MZGHF         |     1 |     3 |     0   (0)| 00:00:01 |
|* 19 |   TABLE ACCESS BY INDEX ROWID         | MS_GHKS             |     1 |    40 |     1   (0)| 00:00:01 |
|* 20 |    INDEX RANGE SCAN                   | I_MS_GHKS_KSDM      |     1 |       |     0   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

  12 - access(TO_NUMBER("KSDM")=75)
  13 - access("MS_YYHY"."GZRQ"=TO_DATE(' 2024-04-11 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
              "MS_YYHY"."YSDM"='650')
  14 - filter(TO_NUMBER("MS_YYHY"."KSDM")=75 AND "MS_YYHY"."KSDM"="MS_GHKS"."KSDM")
  15 - access("ITEM_2"="GY_YGDM"."YGDM")
  17 - access("MS_YSKS"."MZKS"="ITEM_1" AND "MS_YSKS"."YSDM"="GY_YGDM"."YGDM")
  18 - access("MS_YSKS"."FYXH"="MS_MZGHF"."FYXH")
  19 - filter("A"."JGID" IS NOT NULL AND "A"."JGID"="B"."JGID")
  20 - access(TO_NUMBER("KSDM")=75)


Statistics
----------------------------------------------------------
        806  recursive calls
          0  db block gets
        231  consistent gets
          0  physical reads
          0  redo size
        529  bytes sent via SQL*Net to client
        509  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed
--//确实是consistent gets=231,看看硬分析导致806次递规调用.开发应该重视合理地使用绑定变量.

--//第2次执行,逻辑读就是1.
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          1  consistent gets
          0  physical reads
          0  redo size
        529  bytes sent via SQL*Net to client
        509  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

--//再次看出没有使用绑定变量带来问题.
--//另外一点注意的地方是在会话设置statistics_level=all,看执行计划的逻辑读并没有把一些递归执行的逻辑读记入.
--//实际上如果看出有执行多次就很容易发现这个细节问题:
SYS@127.0.0.1:9014/ywdb> @ ffms 8680396602758190538 200

SQL_ID        CHILD_NUMBER    INST_ID FIRST_LOAD_TIME      PLAN_HASH_VALUE ELAPSED_TIME EXECUTIONS BUFFER_GETS ROWS_PROCESSED LIOS_PER_EXEC ROWS_PER_EXEC AVG_ELA_TIME
------------- ------------ ---------- -------------------- --------------- ------------ ---------- ----------- -------------- ------------- ------------- ------------
...
1yht54qu3rpuy            0          2 2024-04-10/10:30:28       1874477375        66895          1         231              0           231             0        66895
88xpu4vgq7h3s            0          2 2024-04-10/10:30:28       1874477375       113700          2         232              0           116             0        56850
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
373a3r0sbhfbc            0          2 2024-04-10/10:30:25       1874477375        74739          1         235              0           235             0        74739
g0rj4kuhv7x65            0          2 2024-04-10/10:30:25       1874477375        60312          1         235              0           235             0        60312
f002tj5fjbv0a            0          1 2024-04-10/10:30:25       1874477375        79006          1         235              0           235             0        79006
5x4mqfw7vuphh            0          1 2024-04-10/10:30:25       1874477375       118722          2         240              0           120             0        59361
200 rows selected.

3.附上相关脚本:
$ cat fms.sql
-- Copyright 2023 lfree. All rights reserved.
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms and conditions.
--------------------------------------------------------------------------------
--
-- File name:  fms.sql  v1.0
-- Purpose:    Query gv$active_session_history Force_Matching_Signature the same, sql_id different of information
-- Author:     lfree
--
-- Usage:
--    @ fms <count(*)_number> <display_record_number> <fromtime> <totime>
--   <count(*)_number>=2>
--
-- Example:
--    @ fms 5 30 &day
--
-- Other:
--     This script uses only the in-memory GV$ACTIVE_SESSION_HISTORY, use
--     @dfms.sql for accessiong the DBA_HIST_ACTIVE_SESS_HISTORY archive
--
--------------------------------------------------------------------------------
WITH a1 AS (SELECT sql_id,force_matching_signature, count(*) cnt1
  FROM gv$active_session_history
 WHERE force_matching_signature <> 0 AND sample_time BETWEEN &3 AND &4 and sql_opname<>'INSERT'
 GROUP BY sql_id, force_matching_signature ) ,
    a2 AS (SELECT force_matching_signature, count(*) sql_id_count,sum(cnt1) total_seconds
  FROM a1
 GROUP BY force_matching_signature
HAVING count(*) >=  &&1
 ORDER BY 3 desc)
SELECT force_matching_signature, sql_id_count,total_seconds
  FROM a2
 WHERE rownum <= &2;

--//显示字段顺序做了一些调整.
$ cat ffms.sql
-- Copyright 2023 lfree. All rights reserved.
-- Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms and conditions.
--------------------------------------------------------------------------------
--
-- File name:   ffms.sql
-- Purpose:     find  force_matching_signature from gv$sql
--
-- Author:      lfree
--
-- Usage:
--     @ ffms FORCE_MATCHING_SIGNATURE <display_record_number>
--
--------------------------------------------------------------------------------

SELECT REPLACE (sql_fulltext, CHR (13), '') c200
  FROM gv$sqlarea
 WHERE FORCE_MATCHING_SIGNATURE = &&1 AND ROWNUM = 1;

prompt
prompt time unit : microsecond
prompt

column FIRST_LOAD_TIME format a20

SELECT *
  FROM (  SELECT sql_id
                ,child_number
                ,inst_id
                ,first_load_time
                ,plan_hash_value
                ,elapsed_time
                ,executions
                ,buffer_gets
                ,rows_processed
                ,ROUND (buffer_gets / nullif(executions,0),2) lios_per_exec
                ,ROUND (rows_processed / nullif(executions,0),2) rows_per_exec
                ,ROUND (elapsed_time / nullif(executions,0),2) avg_ela_time
            FROM gv$sql
           WHERE FORCE_MATCHING_SIGNATURE = &&1
        ORDER BY 4 DESC)
 WHERE ROWNUM <= &&2;

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3013373/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7969561