Rumah pangkalan data tutorial mysql [慢查优化]联表查询注意哪位高手是驱动表 & 你搞不清楚

[慢查优化]联表查询注意哪位高手是驱动表 & 你搞不清楚

Jun 07, 2016 pm 04:14 PM
amp pengoptimuman Pertanyaan Notis memandu tuan

[慢查优化]联表查询注意谁是驱动表 你搞不清楚谁join谁更好时请放手让mysql自行判定 写在前面的话: ?? 不要求每个人一定理解 联表查询 (join/left join/inner join 等 ) 时的 mysql 运算过程; ??? 不要求每个人一定知道线上 (现在或未来) 哪张表数据量大

[慢查优化]联表查询注意谁是驱动表 & 你搞不清楚谁join谁更好时请放手让mysql自行判定

写在前面的话:

?? 不要求每个人一定理解 联表查询(join/left join/inner join)时的mysql运算过程;

???不要求每个人一定知道线上(现在或未来)哪张表数据量大,哪张表数据量小;

????但把mysql客户端(如SQLyog,如HeidiSQL)放在桌面上,时不时拿出来 explain 一把,这是一种美德


在实例讲解之前,我们先回顾一下联表查询的基础知识。

——联表查询的基础知识——

引子:为什么第一个查询using temporary,第二个查询不用临时表呢?

下面两个查询,它们只差了一个order by,效果却迥然不同。

第一个查询:

EXPLAIN extended

SELECT ads.id

FROM ads, city?

WHERE

? ?city.city_id = 8005

? ?AND ads.status = 'online'

? ?AND city.ads_id=ads.id

ORDER BY?ads.id?desc

执行计划为:

??? id? select_type? table?? type??? possible_keys?? key????? key_len? ref???????????????????? rows? filtered? Extra???????????????????????? ?
------? -----------? ------? ------? --------------? -------? -------? --------------------? ------? --------? -------------------------------
???? 1? SIMPLE?????? city??? ref???? ads_id,city_id? city_id? 4??????? const?????????????????? 2838??? 100.00? Using temporary; Using filesort
???? 1? SIMPLE?????? ads???? eq_ref? PRIMARY???????? PRIMARY? 4??????? city.ads_id?????? 1??? 100.00? Using where???????????????????

第二个查询:

EXPLAIN extended

SELECT ads.id

FROM ads,city?

WHERE

? ?city.city_id =8005

? ?AND ads.status = 'online'

? ?AND city.ads_id=ads.id

ORDER BY?city.ads_id?desc

执行计划里没有了using temporary: ??? id? select_type? table?? type??? possible_keys?? key????? key_len? ref???????????????????? rows? filtered? Extra???????????????????? ?
------? -----------? ------? ------? --------------? -------? -------? --------------------? ------? --------? ---------------------------
???? 1? SIMPLE?????? city??? ref???? ads_id,city_id? city_id? 4??????? const?????????????????? 2838??? 100.00? Using where; Using filesort
???? 1? SIMPLE?????? ads??? eq_ref? PRIMARY???????? PRIMARY? 4??????? city.ads_id?????? 1??? 100.00? Using where??????????????? 为什么? ? DBA告诉我们: ? ? MySQL 表关联的算法是 Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。 ? EXPLAIN 结果中,第一行出现的表就是驱动表(Important!) ? 以上两个查询语句,驱动表都是 city,如上面的执行计划所示! ? 对驱动表可以直接排序对非驱动表(的字段排序)需要对循环查询的合并结果(临时表)进行排序(Important!) 因此,order by ads.id desc 时,就要先 using temporary 了! ? 驱动表的定义 wwh999?在 2006年总结说,当进行多表连接查询时,?[驱动表]?的定义为:
1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表];
2)未指定联接条件时,行数少的表为[驱动表](Important!)。 ? 忠告:如果你搞不清楚该让谁做驱动表、谁 join 谁,请让 MySQL 运行时自行判断 既然“未指定联接条件时,行数少的表为[驱动表]”了, 而且你也对自己写出的复杂的 Nested Loop Join 不太有把握(如下面的实例所示), 就别指定谁 left/right join 谁了, 请交给 MySQL优化器 运行时决定吧。 如果您对自己特别有信心,可以像火丁一样做优化。 ? 小结果集驱动大结果集 de.cel?在2012年总结说,不管是你,还是 MySQL, 优化的目标是尽可能减少JOIN中Nested Loop的循环次数, 以此保证:
永远用小结果集驱动大结果集(Important!)

——实例讲解—— ? Nested Loop Join慢查SQL语句 先了解一下 mb 表有 千万级记录,mbei 表要少得多。慢查实例如下:
explain SELECT mb.id, …… FROMmb?LEFT JOIN mbei ON mb.id=mbei.mb_id?INNER JOINu ON mb.uid=u.uid ? WHERE 1=1 ? ORDER BY mbei.apply_time DESC limit 0,10
够复杂吧。Nested Loop Join 就是这样, 以驱动表的结果集作为循环的基础数据,然后将结果集中的数据作为过滤条件一条条地到下一个表中查询数据,最后合并结果;此时还有第三个表,则将前两个表的 Join 结果集作为循环基础数据,再一次通过循环查询条件到第三个表中查询数据,如此反复。 这条语句的执行计划如下: ??? id? select_type? table?? type??? possible_keys?? key???????????? key_len? ref???????????????????? rows? Extra????????????????????????????????????? ?
------? -----------? ------? ------? --------------? --------------? -------? -------------------? -------? --------------------------------------------
???? 1? SIMPLE?????? mb????? index?? userid????????? userid????????? 4??????? (NULL)?????????????? 6060455? Using index; Using temporary; Using filesort
???? 1? SIMPLE?????? mbei??? eq_ref? mb_id? mb_id? 4??????? mb.id???????????? 1???????????????????????????????????????????? ?
???? 1? SIMPLE?????? u?????? eq_ref? PRIMARY???????? PRIMARY???????? 4??????? mb.uid??????? 1? Using index???????????????????????????????? 由于动用了“LEFT JOIN”,所以攻城狮已经指定了驱动表,虽然这张驱动表的结果集记录数达到百万级! . . 如何优化? . . 优化第一步:LEFT JOIN改为JOIN 干嘛要 left join 啊?直接 join!
explain SELECT mb.id……
FROM mb?JOIN mbei ON mb.id=mbei.mb_id?INNER JOINu ON mb.uid=u.uid ? WHERE 1=1 ? ORDER BY mbei.apply_time DESC limit 0,10
立竿见影,驱动表立刻变为小表 mbei 了, Using temporary 消失了,影响行数少多了: ??? id? select_type? table?? type??? possible_keys?? key????? key_len? ref???????????????????????????? rows? Extra??????? ?
------? -----------? ------? ------? --------------? -------? -------? ----------------------------? ------? --------------
???? 1? SIMPLE?????? mbei??? ALL???? mb_id? (NULL)?? (NULL)?? (NULL)???????????????????????? 13383? Using filesort
???? 1? SIMPLE?????? mb????? eq_ref? PRIMARY,userid? PRIMARY? 4??????? mbei.mb_id?????? 1?????????????? ?
???? 1? SIMPLE?????? u?????? eq_ref? PRIMARY???????? PRIMARY? 4??????? mb.uid??????????????? 1? Using index??
优化第一步之分支1:根据驱动表的字段排序,好吗?
left join不变。干嘛要根据非驱动表的字段排序呢?我们前面说过“对驱动表可以直接排序,对非驱动表(的字段排序)需要对循环查询的合并结果(临时表)进行排序!”的。
explain SELECT mb.id……
FROM mb LEFT JOIN mbei ON mb.id=mbei.mb_id?INNER JOINu ON mb.uid=u.uid ? WHERE 1=1 ? ORDER BY?mb.id DESC limit 0,10
也满足业务场景,做到了rows最小: ??? id? select_type? table?? type??? possible_keys?? key???????????? key_len? ref??????????????????? rows? Extra???? ?
------? -----------? ------? ------? --------------? --------------? -------? -------------------? ------? -----------
???? 1? SIMPLE?????? mb????? index?? userid????????? PRIMARY???????? 4??????? (NULL)?????????????????? 10??????????? ?
???? 1? SIMPLE?????? mbei??? eq_ref? mb_id? mb_id? 4??????? mb.id??????????? 1? Using index
???? 1? SIMPLE?????? u?????? eq_ref? PRIMARY???????? PRIMARY???????? 4??????? mb.uid?????? 1? Using index ?
优化第二步:去除所有JOIN,让MySQL自行决定!
写这么多密密麻麻的 left join/inner join 很开心吗?
explain SELECT mb.id……
FROM mb,mbei,u? ?
WHERE
?? ?mb.id=mbei.mb_id
?? ?and mb.uid=u.user_id
order by mbei.apply_time desc
limit 0,10
立竿见影,驱动表一样是小表 mbei: ??? id? select_type? table?? type??? possible_keys?? key????? key_len? ref???????????????????????????? rows? Extra??????? ?
------? -----------? ------? ------? --------------? -------? -------? ----------------------------? ------? --------------
???? 1? SIMPLE?????? mbei??? ALL???? mb_id? (NULL)?? (NULL)?? (NULL)???????????????????????? 13388? Using filesort
???? 1? SIMPLE?????? mb????? eq_ref? PRIMARY,userid? PRIMARY? 4??????? mbei.mb_id?????? 1?????????????? ?
???? 1? SIMPLE?????? u?????? eq_ref? PRIMARY???????? PRIMARY? 4??????? mb.uid??????????????? 1? Using index??
最后的总结:
强调再强调:
不要过于相信你的运气! 不要相信你的开发环境里SQL的执行速度! 请拿起 explain 武器, 如果你看到以下现象,请优化:
  • 出现了Using temporary;
  • rows过多,或者几乎是全表的记录数;
  • key 是 (NULL);
  • possible_keys 出现过多(待选)索引。
? 记住,explain 是一种美德!
? ?
参考资源: 1)wwh999,2006,进行多表查时的排序问题,其多表查询时的原理论证!?; 2)de.cel,2012,MySQL中的Join 原理及优化思路?; 3)火丁,2013,MySQL优化的奇技淫巧之STRAIGHT_JOIN; ? 赠图一枚: /img/2013/10/18/113350732.gif
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
4 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)

Adakah pemandu Logitech ghub tidak menyokong win7? -Mengapa pemacu Logitech ghub hanya boleh dipasang pada pemacu c? Adakah pemandu Logitech ghub tidak menyokong win7? -Mengapa pemacu Logitech ghub hanya boleh dipasang pada pemacu c? Mar 18, 2024 pm 05:37 PM

Adakah pemandu Logitech ghub tidak menyokong win7? Tidak serasi. Memandangkan Windows 7 telah berhenti mengemas kini dan bukan lagi sistem pengendalian utama Microsoft, banyak perisian baharu tidak lagi menyokongnya, seperti Logitech ghub. Antara muka utama pemacu Logitech: 1. Antara muka perisian utama berada di sebelah kiri Tiga butang ialah tetapan pencahayaan, butang dan kepekaan. 2. Dalam penetapan antara muka pencahayaan, kesan khas umum adalah agak konvensional, dan kesan audio visual adalah kemuncak Ia boleh menukar warna mengikut frekuensi bunyi, dan boleh ditetapkan mengikut jalur tinggi, tengah dan bes , dengan warna dan kesan yang berbeza. 3. Dalam tetapan butang, pengguna boleh mengeditnya di sini mengikut keperluan khas mereka. 4. Dalam tetapan sensitiviti, ramai pengguna akan mempunyai beberapa tetapan mereka sendiri. Mereka boleh menambah titik penukaran kelajuan DPI dengan sendirinya, tetapi

12306 Cara menyemak rekod pembelian tiket sejarah Cara menyemak rekod pembelian tiket sejarah 12306 Cara menyemak rekod pembelian tiket sejarah Cara menyemak rekod pembelian tiket sejarah Mar 28, 2024 pm 03:11 PM

Muat turun versi terbaharu aplikasi tempahan tiket 12306 Ia adalah perisian pembelian tiket perjalanan yang semua orang sangat berpuas hati dengannya -pengesahan nama untuk membeli tiket dalam talian Semua pengguna Anda boleh membeli tiket perjalanan dan tiket penerbangan dengan mudah dan menikmati diskaun yang berbeza. Anda juga boleh mula menempah tempahan terlebih dahulu untuk merebut tiket Anda boleh menempah hotel atau pemindahan kereta khas Dengan itu, anda boleh pergi ke mana-mana yang anda mahu pergi dan membeli tiket dengan satu klik lebih mudah dan memudahkan semua orang lebih selesa. Kini editor memperincikannya dalam talian Menyediakan 12306 pengguna cara untuk melihat rekod pembelian tiket sejarah. 1. Buka Keretapi 12306, klik Saya di sudut kanan bawah, dan klik Pesanan Saya 2. Klik Dibayar pada halaman pesanan. 3. Pada halaman berbayar

Bagaimana untuk menyemak kelayakan akademik anda di Xuexin.com Bagaimana untuk menyemak kelayakan akademik anda di Xuexin.com Mar 28, 2024 pm 04:31 PM

Bagaimana untuk menyemak kelayakan akademik saya di Xuexin.com? Anda boleh menyemak kelayakan akademik anda di Xuexin.com Ramai pengguna tidak tahu cara menyemak kelayakan akademik mereka di Xuexin.com Seterusnya, editor membawakan tutorial grafik kepada pengguna tentang cara menyemak kelayakan akademik mereka di Xuexin.com pengguna datang dan lihat! Tutorial penggunaan Xuexin.com: Cara menyemak kelayakan akademik anda di Xuexin.com 1. Pintu masuk Xuexin.com: https://www.chsi.com.cn/ 2. Pertanyaan laman web: Langkah 1: Klik pada alamat Xuexin.com di atas untuk masuk ke laman utama Klik [Education Query]; Langkah 4: Pada halaman log masuk Masukkan maklumat dan klik [Log Masuk];

Cara memasang pemacu win11 tanpa tandatangan digital_Tutorial tentang cara berurusan dengan pemandu win11 tanpa tandatangan digital Cara memasang pemacu win11 tanpa tandatangan digital_Tutorial tentang cara berurusan dengan pemandu win11 tanpa tandatangan digital Mar 20, 2024 pm 04:46 PM

Sesetengah pengguna telah menghadapi beberapa masalah semasa memasang pemacu untuk komputer win11 Komputer menggesa bahawa tandatangan digital fail ini tidak dapat disahkan, mengakibatkan ketidakupayaan untuk memasang pemacu. Sila lihat pengenalan berikut untuk butiran. 1. Tekan tetingkap [Win + [Ctrl+Shift+Enter] Buka tetingkap Windows Powershell dengan hak pentadbir 3. tetingkap Kawalan Akaun Pengguna, adakah anda ingin membenarkan aplikasi ini membuat perubahan pada peranti anda; . Pentadbir: Windows Powers

Perbandingan persamaan dan perbezaan antara MySQL dan PL/SQL Perbandingan persamaan dan perbezaan antara MySQL dan PL/SQL Mar 16, 2024 am 11:15 AM

MySQL dan PL/SQL ialah dua sistem pengurusan pangkalan data yang berbeza, mewakili ciri pangkalan data hubungan dan bahasa prosedur masing-masing. Artikel ini akan membandingkan persamaan dan perbezaan antara MySQL dan PL/SQL, dengan contoh kod khusus untuk digambarkan. MySQL ialah sistem pengurusan pangkalan data hubungan popular yang menggunakan Bahasa Pertanyaan Berstruktur (SQL) untuk mengurus dan mengendalikan pangkalan data. PL/SQL ialah bahasa prosedur yang unik untuk pangkalan data Oracle dan digunakan untuk menulis objek pangkalan data seperti prosedur tersimpan, pencetus dan fungsi. sama

Pengoptimuman program C++: teknik pengurangan kerumitan masa Pengoptimuman program C++: teknik pengurangan kerumitan masa Jun 01, 2024 am 11:19 AM

Kerumitan masa mengukur masa pelaksanaan algoritma berbanding saiz input. Petua untuk mengurangkan kerumitan masa program C++ termasuk: memilih bekas yang sesuai (seperti vektor, senarai) untuk mengoptimumkan storan dan pengurusan data. Gunakan algoritma yang cekap seperti isihan pantas untuk mengurangkan masa pengiraan. Hapuskan berbilang operasi untuk mengurangkan pengiraan berganda. Gunakan cawangan bersyarat untuk mengelakkan pengiraan yang tidak perlu. Optimumkan carian linear dengan menggunakan algoritma yang lebih pantas seperti carian binari.

AMD mengeluarkan kemas kini pemacu 24.7.1: prestasi 'Only: Path of the Goddess' meningkat sebanyak 16%, menyokong permainan 'Zero' AMD mengeluarkan kemas kini pemacu 24.7.1: prestasi 'Only: Path of the Goddess' meningkat sebanyak 16%, menyokong permainan 'Zero' Jul 20, 2024 pm 02:52 PM

Menurut berita dari laman web ini pada 20 Julai, AMD semalam (19 Julai) mengeluarkan kemas kini pemacu AMDSoftware: Adrenalin Edition 24.7.1 terbaru, yang menyokong "Sahaja: Laluan Dewi" (berbanding dengan versi sebelumnya, prestasi meningkat sehingga kepada 16%) dan permainan "Zon Sifar". Kemas kini pemacu AMD juga memperkenalkan teknologi Radeon Anti-Lag2 untuk permainan "DOTA2" secara rasmi AMD menyatakan bahawa selepas memasang pemacu ini untuk kad grafik diskret dan paparan teras dengan seni bina AMD RDNA, kelewatan input boleh dikurangkan lagi dan pengalaman permainan dipertingkatkan. AMD juga telah membetulkan banyak pepijat dalam pemacu baharu Maklumatnya adalah seperti berikut: Mendayakan AMD Radeon™ Anti-Lag dan AMDFi

Bagaimana untuk mengoptimumkan item permulaan sistem WIN7 Bagaimana untuk mengoptimumkan item permulaan sistem WIN7 Mar 26, 2024 pm 06:20 PM

1. Tekan kombinasi kekunci (kekunci win + R) pada desktop untuk membuka tetingkap jalankan, kemudian masukkan [regedit] dan tekan Enter untuk mengesahkan. 2. Selepas membuka Registry Editor, kami klik untuk mengembangkan [HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorer], dan kemudian lihat jika terdapat item Serialize dalam direktori Jika tidak, kami boleh klik kanan Explorer, buat item baharu dan namakannya Serialize. 3. Kemudian klik Serialize, kemudian klik kanan ruang kosong dalam anak tetingkap kanan, cipta nilai bit DWORD (32) baharu dan namakannya Bintang

See all articles