Rumah pangkalan data tutorial mysql Oracle 表三种连接方式(SQL优化)

Oracle 表三种连接方式(SQL优化)

Jun 07, 2016 pm 05:32 PM

在查看SQL执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理。

在查看SQL执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理。

一、连接方式:

嵌套循环(Nested Loops (NL))

(散列)哈希连接(Hash Join (HJ))

(归并)排序合并连接(Sort Merge Join (SMJ) )

二、连接说明:

1.Oracle一次只能连接两个表。不管查询中有多少个表,Oracle在连接中一次仅能操作两张表。

2.当执行多个表的连接时,优化器从一个表开始,将它与另一个表连接;然后将中间结果与下一个表连接,以此类推,直到处理完所有表为止。

三、表连接详解:

1. NESTED LOOP

对于被连接的数据子集较小的情况,nested loop连接是个较好的选择。nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个表里面查找,没有索引一般就不会是 nested loops。一般在nested loop中, 驱动表满足条件结果集不大,被驱动表的连接字段要有索引,这样就走nstedloop。如果驱动表返回记录太多,就不适合nested loops了。如果连接字段没有索引,则适合走hash join,因为不需要索引。

可用ordered提示来改变CBO默认的驱动表,可用USE_NL(table_name1 table_name2)提示来强制使用nested loop。

要点如下:
  1)对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择
  2)使用USE_NL(table_name1 table_name2)可是强制CBO 执行嵌套循环连接
  3)Nested loop一般用在连接的表中有索引,,并且索引选择性较好的时候
  4)OIN的顺序很重要,驱动表的记录集一定要小,返回结果集的响应时间是最快的。
  5)Nested loops 工作方式是从一张表中读取数据,访问另一张表(通常是索引)来做匹配,nested loops适用的场合是当一个关联表比较小的时候,效率会更高。

例子如下:

SQL> create table t as select * from user_tables;

表已创建。

SQL> create index index_t on t(table_name);

索引已创建。

SQL> create table t1  as  select * from user_tables where table_name like '%ACCESS%';

表已创建。

SQL> create index index_t1 on t1(table_name);

索引已创建。

SQL> begin
  2  dbms_stats.gather_table_stats(ownname =>'TEST' ,tabname =>'T');
  3  end;
  4  /

PL/SQL 过程已成功完成。

SQL> begin
  2  dbms_stats.gather_table_stats(ownname =>'TEST' ,tabname =>'T');
  3  end;
  4  /

 

由于t1表记录很小作驱动表且t表的建有索引,适合NL,执行计划如下:

SQL> set wrap off;
SQL> set autotrace traceonly;


SQL> select a.table_name,b.table_name from t a,t1 b
  2  where a.table_name = b.table_name;

已选择8行。


执行计划
----------------------------------------------------------
Plan hash value: 3579965632

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

| Id  | Operation            | Name    | Rows  | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------

|  0 | SELECT STATEMENT      |          |    8 |  280 |    4  (0)| 00:00:01

|  1 |  NESTED LOOPS        |          |    8 |  280 |    4  (0)| 00:00:01

|  2 |  INDEX FAST FULL SCAN| INDEX_T  |  1921 | 34578 |    4  (0)| 00:00:01

|*  3 |  INDEX RANGE SCAN    | INDEX_T1 |    1 |    17 |    0  (0)| 00:00:01

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


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

  3 - access("A"."TABLE_NAME"="B"."TABLE_NAME")

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


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        18  consistent gets
          0  physical reads
          0  redo size
        807  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          8  rows processed

SQL> select a.table_name,b.table_name from t1 a,t b
  2  where a.table_name = b.table_name;

已选择8行。


执行计划
----------------------------------------------------------
Plan hash value: 3579965632

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

| Id  | Operation            | Name    | Rows  | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------

|  0 | SELECT STATEMENT      |          |    8 |  280 |    4  (0)| 00:00:01

|  1 |  NESTED LOOPS        |          |    8 |  280 |    4  (0)| 00:00:01

|  2 |  INDEX FAST FULL SCAN| INDEX_T  |  1921 | 34578 |    4  (0)| 00:00:01

|*  3 |  INDEX RANGE SCAN    | INDEX_T1 |    1 |    17 |    0  (0)| 00:00:01

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


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

  3 - access("A"."TABLE_NAME"="B"."TABLE_NAME")

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

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

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana anda mengubah jadual di MySQL menggunakan pernyataan Alter Table? Bagaimana anda mengubah jadual di MySQL menggunakan pernyataan Alter Table? Mar 19, 2025 pm 03:51 PM

Artikel ini membincangkan menggunakan pernyataan jadual Alter MySQL untuk mengubah suai jadual, termasuk menambah/menjatuhkan lajur, menamakan semula jadual/lajur, dan menukar jenis data lajur.

Bagaimana saya mengkonfigurasi penyulitan SSL/TLS untuk sambungan MySQL? Bagaimana saya mengkonfigurasi penyulitan SSL/TLS untuk sambungan MySQL? Mar 18, 2025 pm 12:01 PM

Artikel membincangkan mengkonfigurasi penyulitan SSL/TLS untuk MySQL, termasuk penjanaan sijil dan pengesahan. Isu utama menggunakan implikasi keselamatan sijil yang ditandatangani sendiri. [Kira-kira aksara: 159]

Bagaimana anda mengendalikan dataset besar di MySQL? Bagaimana anda mengendalikan dataset besar di MySQL? Mar 21, 2025 pm 12:15 PM

Artikel membincangkan strategi untuk mengendalikan dataset besar di MySQL, termasuk pembahagian, sharding, pengindeksan, dan pengoptimuman pertanyaan.

Apakah beberapa alat GUI MySQL yang popular (mis., MySQL Workbench, phpmyadmin)? Apakah beberapa alat GUI MySQL yang popular (mis., MySQL Workbench, phpmyadmin)? Mar 21, 2025 pm 06:28 PM

Artikel membincangkan alat MySQL GUI yang popular seperti MySQL Workbench dan PHPMyAdmin, membandingkan ciri dan kesesuaian mereka untuk pemula dan pengguna maju. [159 aksara]

Bagaimana anda menjatuhkan jadual di MySQL menggunakan pernyataan jadual drop? Bagaimana anda menjatuhkan jadual di MySQL menggunakan pernyataan jadual drop? Mar 19, 2025 pm 03:52 PM

Artikel ini membincangkan jadual menjatuhkan di MySQL menggunakan pernyataan Jadual Drop, menekankan langkah berjaga -jaga dan risiko. Ia menyoroti bahawa tindakan itu tidak dapat dipulihkan tanpa sandaran, memperincikan kaedah pemulihan dan bahaya persekitaran pengeluaran yang berpotensi.

Bagaimana anda membuat indeks pada lajur JSON? Bagaimana anda membuat indeks pada lajur JSON? Mar 21, 2025 pm 12:13 PM

Artikel ini membincangkan membuat indeks pada lajur JSON dalam pelbagai pangkalan data seperti PostgreSQL, MySQL, dan MongoDB untuk meningkatkan prestasi pertanyaan. Ia menerangkan sintaks dan faedah mengindeks laluan JSON tertentu, dan menyenaraikan sistem pangkalan data yang disokong.

Bagaimana anda mewakili hubungan menggunakan kunci asing? Bagaimana anda mewakili hubungan menggunakan kunci asing? Mar 19, 2025 pm 03:48 PM

Artikel membincangkan menggunakan kunci asing untuk mewakili hubungan dalam pangkalan data, memberi tumpuan kepada amalan terbaik, integriti data, dan perangkap umum untuk dielakkan.

Bagaimanakah saya menjamin MySQL terhadap kelemahan biasa (suntikan SQL, serangan kekerasan)? Bagaimanakah saya menjamin MySQL terhadap kelemahan biasa (suntikan SQL, serangan kekerasan)? Mar 18, 2025 pm 12:00 PM

Artikel membincangkan mendapatkan MySQL terhadap suntikan SQL dan serangan kekerasan menggunakan pernyataan yang disediakan, pengesahan input, dan dasar kata laluan yang kuat. (159 aksara)

See all articles