cari
Rumahpangkalan datatutorial mysqlMySQL 中 Join 的基本实现原理

MySQL 中 Join 的基本实现原理

Jun 07, 2016 pm 04:31 PM
joinmysqlsatuprinsipsahajaasascapai

在 MySQL 中,只有一种 Join 算法,就是大名鼎鼎的 Nested Loop Join,他没有其他很多数据库所提供的 Hash Join,也没有 Sort Merge Join。顾名思义,Nested Loop Join 实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作

在 MySQL 中,只有一种 Join 算法,就是大名鼎鼎的 Nested Loop Join,他没有其他很多数据库所提供的 Hash Join,也没有 Sort Merge Join。顾名思义,Nested Loop Join 实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。如果还有第三个参与 Join,则再通过前两个表的 Join 结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此往复。

还是通过示例和图解来说明吧,后面将通过我个人数据库测试环境中的一个 example(自行设计,非MySQL 自己提供) 数据库中的三个表的 Join 查询来进行示例。

注意:由于这里有些内容需要在MySQL 5.1.18之后的版本中才会体现出来,所以本测试的MySQL 版本为5.1.26

表结构:

sky@localhost : example11:09:32> showcreatetableuser_groupG
***************************
1.row ***************************
Table: user_group
CreateTable: CREATETABLE`user_group`(
`user_id`int(11)NOTNULL,
`group_id`int(11)NOTNULL,
`user_type`int(11)NOTNULL,
`gmt_create`datetimeNOTNULL,
`gmt_modified`datetimeNOTNULL,
`status`varchar(16)NOTNULL,
KEY`idx_user_group_uid`(`user_id`)
)ENGINE=MyISAMDEFAULTCHARSET=utf8
1rowinset(0.00sec)
 
sky@localhost : example11:10:32> showcreatetablegroup_messageG
***************************
1.row ***************************
Table: group_message
CreateTable: CREATETABLE`group_message`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`gmt_create`datetimeNOTNULL,
`gmt_modified`datetimeNOTNULL,
`group_id`int(11)NOTNULL,
`user_id`int(11)NOTNULL,
`author`varchar(32)NOTNULL,
`subject`varchar(128)NOTNULL,
PRIMARYKEY(`id`),
KEY`idx_group_message_author_subject`(`author`,`subject`(16)),
KEY`idx_group_message_author`(`author`),
KEY`idx_group_message_gid_uid`(`group_id`,`user_id`)
)ENGINE=MyISAMAUTO_INCREMENT=97DEFAULTCHARSET=utf8
1rowinset(0.00sec)
 
sky@localhost : example11:10:43> showcreatetablegroup_message_contentG
***************************
1.row ***************************
Table: group_message_content
CreateTable: CREATETABLE`group_message_content`(
`group_msg_id`int(11)NOTNULL,
`content`textNOTNULL,
KEY`group_message_content_msg_id`(`group_msg_id`)
)ENGINE=MyISAMDEFAULTCHARSET=utf8
1rowinset(0.00sec)

使用Query如下:

selectm.subjectmsg_subject, c.contentmsg_content
fromuser_groupg,group_messagem,group_message_contentc
whereg.user_id = 1
andm.group_id = g.group_id
andc.group_msg_id = m.id

看看我们的 Query 的执行计划:

sky@localhost : example11:17:04> explainselectm.subjectmsg_subject, c.contentmsg_content
->
fromuser_groupg,group_messagem,group_message_contentc
->
whereg.user_id = 1
->
andm.group_id = g.group_id
->
andc.group_msg_id = m.idG
***************************
1.row ***************************
id: 1
select_type: SIMPLE
table: g
type: ref
possible_keys: user_group_gid_ind,user_group_uid_ind,user_group_gid_uid_ind
key: user_group_uid_ind
key_len: 4
ref: const
rows: 2
Extra:
***************************
2.row ***************************
id: 1
select_type: SIMPLE
table: m
type: ref
possible_keys: PRIMARY,idx_group_message_gid_uid
key: idx_group_message_gid_uid
key_len: 4
ref: example.g.group_id
rows: 3
Extra:
***************************
3.row ***************************
id: 1
select_type: SIMPLE
table: c
type: ref
possible_keys: idx_group_message_content_msg_id
key: idx_group_message_content_msg_id
key_len: 4
ref: example.m.id
rows: 2
Extra:

我们可以看出,MySQL Query Optimizer 选择了 user_group 作为驱动表,首先利用我们传入的条件 user_id 通过 该表上面的索引 user_group_uid_ind 来进行 const 条件的索引 ref 查找,然后以 user_group 表中过滤出来的结果集的 group_id 字段作为查询条件,对 group_message 循环查询,然后再通过 user_group 和 group_message 两个表的结果集中的? group_message 的 id 作为条件 与 group_message_content 的 group_msg_id 比较进行循环查询,才得到最终的结果。没啥特别的,后一个引用前一个的结果集作为条件,实现过程可以通过下图表示:

下面的我们调整一下 group_message_content 去掉上面的 idx_group_message_content_msg_id 这个索引,然后再看看会是什么效果:

sky@localhost : example11:25:36> dropindexidx_group_message_content_msg_idongroup_message_content;
QueryOK, 96rowsaffected(0.11sec)
 
sky@localhost : example10:21:06> explain
->
selectm.subjectmsg_subject, c.contentmsg_content
->
fromuser_groupg,group_messagem,group_message_contentc
->
whereg.user_id = 1
->
andm.group_id = g.group_id
->
andc.group_msg_id = m.idG
***************************
1.row ***************************
id: 1
select_type: SIMPLE
table: g
type: ref
possible_keys: idx_user_group_uid
key: idx_user_group_uid
key_len: 4
ref: const
rows: 2
Extra:
***************************
2.row ***************************
id: 1
select_type: SIMPLE
table: m
type: ref
possible_keys: PRIMARY,idx_group_message_gid_uid
key: idx_group_message_gid_uid
key_len: 4
ref: example.g.group_id
rows: 3
Extra:
***************************
3.row ***************************
id: 1
select_type: SIMPLE
table: c
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 96
Extra: Usingwhere; Usingjoinbuffer

我们看到不仅仅 group_message_content 表的访问从 ref 变成了 ALL,此外,在最后一行的 Extra信息从没有任何内容变成为? Using where; Using join buffer,也就是说,对于从 ref 变成 ALL 很容易理解,没有可以使用的索引的索引了嘛,当然得进行全表扫描了,Using where 也是因为变成全表扫描之后,我们需要取得的 content 字段只能通过对表中的数据进行 where 过滤才能取得,但是后面出现的 Using join buffer 是一个啥呢?

我们知道,MySQL 中有一个供我们设置的参数 join_buffer_size ,这里实际上就是使用到了通过该参数所设置的 Buffer 区域。那为啥之前的执行计划中没有用到呢?

实际上,Join Buffer 只有当我们的 Join 类型为 ALL(如示例中),index,rang 或者是 index_merge 的时候 才能够使用,所以,在我们去掉 group_message_content 表的 group_msg_id 字段的索引之前,由于 Join 是 ref 类型的,所以我们的执行计划中并没有看到有使用 Join Buffer。

当我们使用了 Join Buffer 之后,我们可以通过下面的这张图片来表示 Join 完成过程:
nested_join_with_buffer

Kenyataan
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
Terangkan peranan log redo innoDB dan membatalkan log.Terangkan peranan log redo innoDB dan membatalkan log.Apr 15, 2025 am 12:16 AM

InnoDB menggunakan redolog dan undologs untuk memastikan konsistensi dan kebolehpercayaan data. 1. Pengubahsuaian halaman data rekod untuk memastikan pemulihan kemalangan dan kegigihan transaksi. 2.UNDOLOGS merekodkan nilai data asal dan menyokong penggantian transaksi dan MVCC.

Apakah metrik utama untuk dicari dalam output yang dijelaskan (jenis, kunci, baris, tambahan)?Apakah metrik utama untuk dicari dalam output yang dijelaskan (jenis, kunci, baris, tambahan)?Apr 15, 2025 am 12:15 AM

Metrik utama untuk menjelaskan arahan termasuk jenis, kunci, baris, dan tambahan. 1) Jenis mencerminkan jenis akses pertanyaan. Semakin tinggi nilai, semakin tinggi kecekapan, seperti const adalah lebih baik daripada semua. 2) Kunci memaparkan indeks yang digunakan, dan null menunjukkan tiada indeks. 3) Baris menganggarkan bilangan baris yang diimbas, yang mempengaruhi prestasi pertanyaan. 4) Tambahan memberikan maklumat tambahan, seperti menggunakanFilesort meminta bahawa ia perlu dioptimumkan.

Apakah status sementara dalam menjelaskan dan bagaimana untuk mengelakkannya?Apakah status sementara dalam menjelaskan dan bagaimana untuk mengelakkannya?Apr 15, 2025 am 12:14 AM

MenggunakanTemary menunjukkan bahawa keperluan untuk membuat jadual sementara dalam pertanyaan MySQL, yang biasanya dijumpai di Orderby menggunakan lajur yang berbeza, GroupBy, atau tidak diindeks. Anda boleh mengelakkan berlakunya indeks dan menulis semula pertanyaan dan meningkatkan prestasi pertanyaan. Khususnya, apabila menggunakan pembelian muncul dalam menjelaskan output, ini bermakna MySQL perlu membuat jadual sementara untuk mengendalikan pertanyaan. Ini biasanya berlaku apabila: 1) deduplikasi atau pengelompokan apabila menggunakan yang berbeza atau kumpulan; 2) Susun apabila Orderby mengandungi lajur bukan indeks; 3) Gunakan subquery kompleks atau menyertai operasi. Kaedah Pengoptimuman termasuk: 1) Orderby dan GroupB

Huraikan tahap pengasingan urus niaga SQL yang berbeza (baca yang tidak komited, baca bacaan yang komited, berulang, bersiri) dan implikasinya dalam MySQL/InnoDB.Huraikan tahap pengasingan urus niaga SQL yang berbeza (baca yang tidak komited, baca bacaan yang komited, berulang, bersiri) dan implikasinya dalam MySQL/InnoDB.Apr 15, 2025 am 12:11 AM

MySQL/InnoDB menyokong empat tahap pengasingan transaksi: ReadUncommitted, ReadCommitted, RepeatableRead dan Serializable. 1. ReadoMuncommitted membolehkan membaca data yang tidak komited, yang boleh menyebabkan bacaan kotor. 2. 3.RepeatableRead adalah tahap lalai, mengelakkan bacaan kotor dan bacaan yang tidak boleh diulang, tetapi bacaan hantu mungkin berlaku. 4. Serializable mengelakkan semua masalah konkurensi tetapi mengurangkan kesesuaian. Memilih tahap pengasingan yang sesuai memerlukan keseimbangan data konsistensi dan keperluan prestasi.

MySQL vs Pangkalan Data Lain: Membandingkan PilihanMySQL vs Pangkalan Data Lain: Membandingkan PilihanApr 15, 2025 am 12:08 AM

MySQL sesuai untuk aplikasi web dan sistem pengurusan kandungan dan popular untuk sumber terbuka, prestasi tinggi dan kemudahan penggunaan. 1) Berbanding dengan PostgreSQL, MySQL melakukan lebih baik dalam pertanyaan mudah dan operasi membaca serentak yang tinggi. 2) Berbanding dengan Oracle, MySQL lebih popular di kalangan perusahaan kecil dan sederhana kerana sumber terbuka dan kos rendah. 3) Berbanding dengan Microsoft SQL Server, MySQL lebih sesuai untuk aplikasi silang platform. 4) Tidak seperti MongoDB, MySQL lebih sesuai untuk data berstruktur dan pemprosesan transaksi.

Bagaimanakah kardinaliti indeks MySQL mempengaruhi prestasi pertanyaan?Bagaimanakah kardinaliti indeks MySQL mempengaruhi prestasi pertanyaan?Apr 14, 2025 am 12:18 AM

Cardinality Indeks MySQL mempunyai kesan yang signifikan terhadap prestasi pertanyaan: 1. Indeks kardinaliti yang tinggi dapat lebih berkesan menyempitkan julat data dan meningkatkan kecekapan pertanyaan; 2. Indeks kardinaliti yang rendah boleh membawa kepada pengimbasan jadual penuh dan mengurangkan prestasi pertanyaan; 3. Dalam indeks bersama, urutan kardinaliti yang tinggi harus diletakkan di depan untuk mengoptimumkan pertanyaan.

MySQL: Sumber dan Tutorial untuk Pengguna BaruMySQL: Sumber dan Tutorial untuk Pengguna BaruApr 14, 2025 am 12:16 AM

Laluan pembelajaran MySQL termasuk pengetahuan asas, konsep teras, contoh penggunaan, dan teknik pengoptimuman. 1) Memahami konsep asas seperti jadual, baris, lajur, dan pertanyaan SQL. 2) Ketahui definisi, prinsip kerja dan kelebihan MySQL. 3) menguasai operasi CRUD asas dan penggunaan lanjutan, seperti indeks dan prosedur yang disimpan. 4) Biasa dengan debugging kesilapan biasa dan cadangan pengoptimuman prestasi, seperti penggunaan rasional indeks dan pertanyaan pengoptimuman. Melalui langkah -langkah ini, anda akan memahami sepenuhnya penggunaan dan pengoptimuman MySQL.

Mysql dunia nyata: Contoh dan kes penggunaanMysql dunia nyata: Contoh dan kes penggunaanApr 14, 2025 am 12:15 AM

Aplikasi dunia nyata MySQL termasuk reka bentuk pangkalan data asas dan pengoptimuman pertanyaan kompleks. 1) Penggunaan Asas: Digunakan untuk menyimpan dan mengurus data pengguna, seperti memasukkan, menanyakan, mengemas kini dan memadam maklumat pengguna. 2) Penggunaan lanjutan: Mengendalikan logik perniagaan yang kompleks, seperti perintah dan pengurusan inventori platform e-dagang. 3) Pengoptimuman Prestasi: Meningkatkan prestasi dengan menggunakan indeks, jadual partisi dan cache pertanyaan.

See all articles

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)
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
1 bulan yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

VSCode Windows 64-bit Muat Turun

VSCode Windows 64-bit Muat Turun

Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

EditPlus versi Cina retak

EditPlus versi Cina retak

Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod

SublimeText3 Linux versi baharu

SublimeText3 Linux versi baharu

SublimeText3 Linux versi terkini

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

DVWA

DVWA

Damn Vulnerable Web App (DVWA) ialah aplikasi web PHP/MySQL yang sangat terdedah. Matlamat utamanya adalah untuk menjadi bantuan bagi profesional keselamatan untuk menguji kemahiran dan alatan mereka dalam persekitaran undang-undang, untuk membantu pembangun web lebih memahami proses mengamankan aplikasi web, dan untuk membantu guru/pelajar mengajar/belajar dalam persekitaran bilik darjah Aplikasi web keselamatan. Matlamat DVWA adalah untuk mempraktikkan beberapa kelemahan web yang paling biasa melalui antara muka yang mudah dan mudah, dengan pelbagai tahap kesukaran. Sila ambil perhatian bahawa perisian ini