Rumah > pangkalan data > Oracle > teks badan

Kuasai sepenuhnya pembelajaran lanjutan Oracle untuk melihat pelan pelaksanaan

WBOY
Lepaskan: 2022-02-24 19:24:33
ke hadapan
2856 orang telah melayarinya

Artikel ini membawakan anda pengetahuan yang berkaitan tentang Oracle, yang terutamanya memperkenalkan isu berkaitan melihat rancangan pelaksanaan saya harap ia akan membantu semua orang.

Kuasai sepenuhnya pembelajaran lanjutan Oracle untuk melihat pelan pelaksanaan

Tutorial yang disyorkan: "Tutorial Video Oracle"

Hari ini kita akan bercakap tentang cara Oracle melihat rancangan pelaksanaan dan cara melihat rancangan pelaksanaan.

1. Cara melihat pelan pelaksanaan

1.1. Tetapkan autotrace

Arahan autotrace adalah seperti berikut

Nombor siri

序号

命令

解释

1

SET AUTOTRACE OFF

此为默认值,即关闭Autotrace

2

SET AUTOTRACE ON EXPLAIN

只显示执行计划

3

SET AUTOTRACE ON STATISTICS

只显示执行的统计信息

4

SET AUTOTRACE ON

包含2,3两项内容

5

SET AUTOTRACE TRACEONLY

与ON相似,但不显示语句的执行结果

Arahan

Penjelasan

1

MATIKAN AUTOTRACE

Ini ialah nilai lalai. Iaitu, matikan Autotrace

2

SET AUTOTRACE PADA EXPLAIN

Tunjukkan rancangan pelaksanaan sahaja

3

SET AUTOTRACE PADA STATISTIK

Hanya paparkan statistik pelaksanaan

4

SET AUTOTRACE HIDUP

Mengandungi dua item 2 dan 3

5

SET AUTOTRACE SAHAJA

Serupa dengan HIDUP, tetapi tidak memaparkan pernyataan Keputusan pelaksanaan

1.2. Gunakan alat pihak ketiga

seperti tetingkap explain PL/SQL Develop

1.3 EXPLAIN PLAN FOR

Dikatakan bahawa menambah pelan sebelum SQL yang dilaksanakan boleh menyemak pelan pelaksanaan >

telah dijelaskan.

SQL> EXPLAIN PLAN FOR SELECT * FROM EMP;
Salin selepas log masuk
Atau:

SQL> SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));
Salin selepas log masuk
2. Kosongkan cache SGA

Kerana apabila sql dilaksanakan, pelan pelaksanaan sql, pangkalan data membaca dari cakera dan maklumat lain Ia akan disimpan dalam beberapa cache SGA untuk satu tempoh masa Untuk melihat kesan pelaksanaan pertama kenyataan, cache ini perlu dikosongkan.
SQL> select * from table(dbms_xplan.display);
Salin selepas log masuk

3. Analisis pelan pelaksanaan

3.1 Cipta jadual ujian
ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH GLOBAL CONTEXT;
Salin selepas log masuk

Buat dua jadual baharu, cust_info dan cst_tran (hanya untuk ujian, tiada kepentingan praktikal)

Masukkan beberapa data, 10,000 dalam jadual CUST_INFO dan 1 juta dalam jadual CST_TRAN.

CREATE TABLE CUST_INFO
(CST_NO NUMBER,
CST_NAME VARCHAR2(50),
AGE SMALLINT);

CREATE TABLE CST_TRAN
(
CST_NO NUMBER,
TRAN_DATE VARCHAR2(8),
TRAN_AMT NUMBER(19,3)
);
Salin selepas log masuk
3.2. Lihat rancangan pelaksanaan

Lihat rancangan pelaksanaan yang dikaitkan dengan kedua-dua jadual ini
INSERT INTO CUST_INFO
SELECT 100000+LEVEL,
       'test'||LEVEL,
       ROUND(DBMS_RANDOM.VALUE(1,100))
FROM DUAL
CONNECT BY LEVEL<=10000;


INSERT INTO CST_TRAN
WITH AA AS
(SELECT LEVEL FROM DUAL CONNECT BY LEVEL<=100)
SELECT T.CST_NO,
       TO_CHAR(SYSDATE - DBMS_RANDOM.VALUE(1,1000),&#39;yyyymmdd&#39;),
       ROUND(DBMS_RANDOM.VALUE(1,999999999),3)
FROM CUST_INFO T
INNER JOIN AA
ON 1=1;
Salin selepas log masuk

3.2.1 > Mula-mula, mari kita lihat bahagian pertama

SQL> SELECT T.CST_NO, T.CST_NAME, G.TRAN_DATE, G.TRAN_AMT FROM CUST_INFO T INNER JOIN CST_TRAN G ON G.CST_NO = T.CST_NO;

1000000 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 2290587575

--------------------------------------------------------------------------------
| Id  | Operation                        | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                     |   996K|    68M|  1079     (2)| 00:00:13 |
|*  1 |  HASH JOIN                   |                     |   996K|    68M|  1079     (2)| 00:00:13 |
|   2 |   TABLE ACCESS FULL | CUST_INFO | 10000 |   390K|    11     (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL | CST_TRAN  |  1065K|    32M|  1064     (1)| 00:00:13 |
--------------------------------------------------------------------------------

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

   1 - access("G"."CST_NO"="T"."CST_NO")

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
    561  recursive calls
      0  db block gets
      70483  consistent gets
       4389  physical reads
      0  redo size
   45078003  bytes sent via SQL*Net to client
     733845  bytes received via SQL*Net from client
      66668  SQL*Net roundtrips to/from client
     10  sorts (memory)
      0  sorts (disk)
    1000000  rows processed
Salin selepas log masuk

penerangan medan dalam rancangan pelaksanaan:

--------------------------------------------------------------------------------
| Id  | Operation                        | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                     |   996K|    68M|  1079     (2)| 00:00:13 |
|*  1 |  HASH JOIN                   |                     |   996K|    68M|  1079     (2)| 00:00:13 |
|   2 |   TABLE ACCESS FULL | CUST_INFO | 10000 |   390K|    11     (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL | CST_TRAN  |  1065K|    32M|  1064     (1)| 00:00:13 |
--------------------------------------------------------------------------------
Salin selepas log masuk

ID: nombor urutan, tetapi bukan urutan pelaksanaan. Urutan pelaksanaan dinilai berdasarkan lekukan. Operasi: Kandungan operasi semasa.

Baris: Kerdinalitian operasi semasa, Oracle menganggarkan set hasil pulangan bagi operasi semasa.
  • Kos (CPU): Nilai (kos) yang dikira oleh Oracle untuk menggambarkan kos pelaksanaan SQL.
  • Masa: Oracle menganggarkan masa operasi semasa.
  • Arahan:
  • 1 Operasi

Rekodkan operasi setiap langkah, dan nilaikan susunan pelaksanaan mengikut tahap lekukan. Dalam pangkalan data OLAP, terdapat banyak sambungan HASH JOIN, terutamanya apabila set data yang dikembalikan adalah besar, ia pada asasnya HASH JOIN.

2. Baris

Nilai baris menunjukkan bilangan rekod yang CBO jangkakan untuk dikembalikan daripada sumber baris ini mungkin jadual, indeks atau subkueri . Dalam pelan pelaksanaan dalam Oracle 9i, Cardinality disingkatkan sebagai Card. Dalam 10g, nilai Kad digantikan dengan baris. Nilai

baris

adalah penting untuk CBO

membuat rancangan pelaksanaan yang betul.

Jika nilai baris yang diperolehi oleh CBO tidak cukup tepat (biasanya disebabkan kekurangan analisis atau data analisis yang lapuk), akan berlaku penyelewengan dalam pengiraan kos pelan pelaksanaan, mengakibatkan CBO salah merumuskan pelan pelaksanaan. Apabila terdapat pertanyaan berkaitan berbilang jadual atau subkueri dalam SQL, nilai baris setiap jadual atau subkueri yang berkaitan mempunyai kesan yang besar pada pertanyaan utama Malah boleh dikatakan bahawa CBO bergantung pada setiap yang berkaitan jadual. Atau nilai baris subquery mengira rancangan pelaksanaan akhir. Untuk pertanyaan berbilang jadual, CBO menggunakan bilangan baris (baris) yang dikembalikan oleh setiap jadual yang berkaitan untuk menentukan kaedah akses yang hendak digunakan untuk perkaitan jadual (seperti Gabungan gelung Bersarang atau Sertai cincang) 3. Kos (CPU) dan Masa adalah nilai rujukan penting untuk pelan pelaksanaan

3.2.2. Penerangan predikat:

Maklumat Predikat (dikenal pasti oleh id operasi):

-------------------------------------------- ----- ---

1 - akses("G"."CST_NO"="T"."CST_NO")

Nota

-----
- pensampelan dinamik yang digunakan untuk pernyataan ini (tahap=2)

Akses: Menunjukkan bahawa nilai keadaan predikat ini akan mempengaruhi laluan akses data (jadual atau indeks).

Penapis: Menunjukkan bahawa nilai keadaan predikat tidak akan menjejaskan laluan akses data dan hanya memainkan peranan penapisan. (Tidak dalam contoh ini)

Nota: Dalam predikat, beri perhatian kepada

akses

Pertimbangkan syarat predikat dan sama ada laluan akses yang digunakan betul.

3.2.3、统计信息

Statistics
----------------------------------------------------------
    561  recursive calls
      0  db block gets
      70483  consistent gets
       4389  physical reads
      0  redo size
   45078003  bytes sent via SQL*Net to client
     733845  bytes received via SQL*Net from client
      66668  SQL*Net roundtrips to/from client
     10  sorts (memory)
      0  sorts (disk)
    1000000  rows processed
Salin selepas log masuk

参数说明:

  • recursive calls :递归调用。一般原因:dictionary cache未命中;动态存储扩展;PL/SQL语句
  • db block gets :bufer中读取的block数量,用于insert,update,delete,selectfor update
  • consistent gets :这里是一致读次数(一个block可能会被读多次),bufer中读取的用于查询(除掉select forupdate)的block数量。
  • physical reads :从磁盘上读取的block数量,敬请关注每周五晚免费网络公开课。
  • redo size :bytes,写到redo logs的数据量
  • bytes sent via SQL*Net to client :发送给客户端的字节数
  • bytes received via SQL*Net from client :从客户端接收的字节数
  • SQL*Net roundtrips to/from client :与客户端的交互次数(个人理解接收一条SQL语句,执行结果分多次发送给客户端,如有问题请指正
  • sorts (memory) :内存排序次数
  • sorts (disk) :磁盘排序次数;与sort_area_size有关
  • rows processed :执行完SQL后返回结果集的行数

四、部分信息解释

4.1、SQL*Net roundtrips to/from client的计算方式

这个指标的计算方式和一个参数息息相关,arraysize

arraysize是什么呢?

请查阅大牛博文:Oracle arraysize 和 fetch size 参数 与 性能优化 说明

arraysize定义了一次返回到客户端的行数,取值范围【1-5000】,默认15。

使用命令在数据库中查看arraysize的值。

show arraysize

还可以修改这个值

set arraysize 5000;

明白了arraysize这个参数就可以计算SQL*Net roundtrips to/from client的值了。上例中,返回客户端结果集的行数是1000000,默认arraysize值是15,1000000/15向上取整等于66667。

为啥要向上取整?

举个栗子,如果有10个苹果,一个只能拿3个,几次可以拿完,3次可以拿9个,还剩1个,所以还需要再拿一次,共4次。

统计分析中的值是66668,为什么我们计算的值是66667?

就要看这个指标本身了,再粘贴一次:SQL*Net roundtrips to/from client 重点看from,意思是我们还要接受一次客户端发来的SQL语句,因此是:66667+1,本问题纯属个人臆断,无真凭实据,受限于本人的知识水平,如有误,请指出。

将arraysize的值修改为5000后,再观察SQL*Net roundtrips to/from client的变化,结果为201。

前面提到 arraysize的取值范围是【1-5000】,我们可以试一下改为不在这个区间的值,比如改为0,结果报错了

SQL> set arraysize 0;
SP2-0267: arraysize option 0 out of range (1 through 5000)
Salin selepas log masuk

4.2、consistent gets

译为中文就是:一致性读, 好抽象的一个指标,啥叫一致性读,心中无数羊驼驼在大海中狂奔。

官网对consistent gets 的解释:

consistent gets:Number of times a consistent read wasrequested for a block.

通常我们执行SQL查询时涉及的每一block都是Consistent Read, 只是有些CR(Consistent Read)需要使用undo 来进行构造, 大部分CR(Consistent Read)并不涉及到undo block的读.

还有就是每次读这个block都是一次CR(可能每个block上有多个数据row), 也就是如果某个block被读了10次, 系统会记录10个Consistent Read.

如果想深入学习,请参考大佬博文:Oracle 有关 Consistent gets 的测试 -- cnDBA.cn_中国DBA社区

接来下测试下, consistent gets是从哪来的,需要使用有sysdba权限的用户,因为oradebug工具需要sysdba权限。

oradebug工具介绍:oracle实用工具:oradebug

使用10046对同一条数据跟踪两次,注意观察 consistent gets的不同

为了不影响测试结果,首先清空缓存

SQL> ALTER SYSTEM FLUSH SHARED_POOL;
System altered.
SQL> ALTER SYSTEM FLUSH BUFFER_CACHE;
System altered.
SQL> ALTER SYSTEM FLUSH GLOBAL CONTEXT;
System altered.
Salin selepas log masuk

第一次执行

SQL> set tim on timing on
00:42:30 SQL> set autot trace stat
00:42:36 SQL> oradebug setmypid
Statement processed.
00:42:42 SQL> alter session set tracefile_identifier=&#39;chf1&#39;;

Session altered.

Elapsed: 00:00:00.01
00:42:50 SQL> oradebug event 10046 trace name context forever,level 12;
Statement processed.
00:42:57 SQL> SELECT T.CST_NO, T.CST_NAME, G.TRAN_DATE, G.TRAN_AMT FROM CHF.CUST_INFO T INNER JOIN CHF.CST_TRAN G ON G.CST_NO = T.CST_NO;

1000000 rows selected.

Elapsed: 00:00:22.71

Statistics
----------------------------------------------------------
    547  recursive calls
      0  db block gets
      70368  consistent gets
       3898  physical reads
      0  redo size
   45078003  bytes sent via SQL*Net to client
     733845  bytes received via SQL*Net from client
      66668  SQL*Net roundtrips to/from client
     10  sorts (memory)
      0  sorts (disk)
    1000000  rows processed

00:44:24 SQL> oradebug event 10046 trace name context off;
Statement processed.
00:45:54 SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orcl/bpas/trace/bpas_ora_7715_chf1.trc
Salin selepas log masuk

第二次执行

00:46:04 SQL> alter session set tracefile_identifier=&#39;chf2&#39;;

Session altered.

Elapsed: 00:00:00.00
00:46:35 SQL> oradebug event 10046 trace name context forever,level 12;
Statement processed.
00:46:43 SQL> SELECT T.CST_NO, T.CST_NAME, G.TRAN_DATE, G.TRAN_AMT FROM CHF.CUST_INFO T INNER JOIN CHF.CST_TRAN G ON G.CST_NO = T.CST_NO;

1000000 rows selected.

Elapsed: 00:00:21.62

Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
      70301  consistent gets
       3850  physical reads
      0  redo size
   45078003  bytes sent via SQL*Net to client
     733845  bytes received via SQL*Net from client
      66668  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
    1000000  rows processed

00:47:11 SQL> oradebug event 10046 trace name context off;
Statement processed.
00:49:03 SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/orcl/bpas/trace/bpas_ora_7715_chf2.trc
Salin selepas log masuk

通过对比两次执行,发现consistent gets、physical reads、sorts (memory)都有变化,这是因为SGA中已经缓存了部分数据块。

再对比下我们刚才生产的两个跟踪日志,为方便查看,先将其格式转换以下

[oracle@localhost ~]$ tkprof /u01/app/oracle/diag/rdbms/orcl/bpas/trace/bpas_ora_7715_chf1.trc /u01/chf1.trc

TKPROF: Release 11.2.0.1.0 - Development on Wed Dec 8 00:53:37 2021

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.


[oracle@localhost ~]$ tkprof /u01/app/oracle/diag/rdbms/orcl/bpas/trace/bpas_ora_7715_chf2.trc /u01/chf2.trc

TKPROF: Release 11.2.0.1.0 - Development on Wed Dec 8 00:53:48 2021

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
Salin selepas log masuk

打开 /u01/chf1.trc,下面贴出部分重要信息

OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.03       0.03          8         67          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch    66668      0.76       3.24       3890      70301          0     1000000
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    66670      0.79       3.28       3898      70368          0     1000000

Misses in library cache during parse: 1

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                   66670        0.01          0.14
  SQL*Net message from client                 66670       64.54         79.11
  db file sequential read                         5        0.00          0.00
  Disk file operations I/O                        1        0.00          0.00
  db file scattered read                          5        0.00          0.00
  asynch descriptor resize                        4        0.00          0.00
  direct path read                               69        0.00          0.02


OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse       12      0.00       0.00          0          0          0           0
Execute     24      0.01       0.01          0          0          0           0
Fetch       30      0.00       0.00          8         67          0          18
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       66      0.02       0.02          8         67          0          18
Salin selepas log masuk

打开 /u01/chf2.trc,下面贴出部分重要信息

OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch    66668      1.57       3.73       3850      70301          0     1000000
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    66670      1.57       3.73       3850      70301          0     1000000
Misses in library cache during parse: 0
Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                   66670        0.00          0.10
  SQL*Net message from client                 66670        6.83         19.93
  asynch descriptor resize                        4        0.00          0.00
  direct path read                               69        0.00          0.01
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        0      0.00       0.00          0          0          0           0
Execute      0      0.00       0.00          0          0          0           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        0      0.00       0.00          0          0          0           0
Salin selepas log masuk

比较发现,第一次执行解析SQL语句,生产执行计划时,consistent gets发生67次,执行SQL语句时发生70301。第一次执行解析SQL语句,生产执行计划时,因已经有缓存,所以consistent gets发生0次,执行SQL语句时发生70301。

推荐教程:《Oracle视频教程

Atas ialah kandungan terperinci Kuasai sepenuhnya pembelajaran lanjutan Oracle untuk melihat pelan pelaksanaan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:csdn.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan