MySQL ialah pangkalan data yang biasa digunakan dalam projek, dan dalam pertanyaan juga sangat biasa digunakan. Semasa penyahpepijatan projek baru-baru ini, saya menemui pertanyaan pilihan yang tidak dijangka, yang sebenarnya mengambil masa 33 saat!
1. jadual maklumat pengguna
2. jadual artikel
select*fromuserinfowhereidin(selectauthor_idfromartilcewheretype=1);
Apabila anda mula-mula melihat SQL di atas, anda mungkin berfikir bahawa ia adalah subkueri yang sangat mudah. Mula-mula ketahui author_id, dan kemudian gunakan untuk menanyakannya.
Jika ada indeks yang berkaitan, ia akan menjadi sangat cepat dari segi pembongkaran, ia adalah seperti berikut:
1.selectauthor_idfromartilcewheretype=1; 2.select*fromuserinfowhereidin(1,2,3);
Tetapi hakikatnya begini:
mysql> select count(*) from userinfo;
mysql> select count(*) from article;
mysql> select id,username from userinfo where id in (select author_id from article where type = 1);
33 saat! Kenapa lambat sangat?
Rujukan:
https://dev.mysql.com/doc/refman/5.5/en/subquery-optimization.html
1. Gunakan meja sementara
select id,username from userinfo where id in (select author_id from (select author_id from article where type = 1) as tb);
2. Guna join
select a.id,a.username from userinfo a, article b where a.id = b.author_id and b.type = 1;
Sebagai contoh, subkueri IN berikut tidak berkorelasi (di mana_condition hanya melibatkan lajur dari t2 dan bukan t1):
pilih * daripada t1
di mana t1.a masuk (pilih t2.b daripada t2 di mana di mana_syarat);Pengoptimum
mungkin menulis semula ini sebagai subquery berkorelasi EXISTS
:pilih * daripada t1
di mana wujud (pilih t2.b daripada t2 di mana where_condition dan t1.a=t2.b);
Penciptaan subkuerimenggunakan jadual sementara mengelakkan penulisan semula sedemikian dan memungkinkan untuk melaksanakan subkueri hanya sekali dan bukannya sekali setiap baris pertanyaan luar
.https://dev.mysql.com/doc/refman/5.6/ms/subquery-materialization.html
Artikel itu datang dari akaun awam WeChat: HULK rundingan teknikal barisan hadapan
Atas ialah kandungan terperinci Ingat untuk memijak 'pit' MySQL dalam subquery. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!