Rumah >pangkalan data >tutorial mysql >Analisis masalah yang memadam dalam subquery tidak pergi ke indeks dalam mysql
Pembelajaran yang disyorkan: tutorial video mysql
Sebelum artikel dimulakan, izinkan saya bertanyakan soalan kepada anda: padam masuk subquery , adakah ia akan diindeks? Tanggapan pertama ramai rakan kongsi ialah mereka tahu cara mengindeks. Baru-baru ini kami menghadapi masalah pengeluaran yang berkaitan dengannya. Artikel ini akan membincangkan isu ini dengan semua orang dan melampirkan pelan pengoptimuman.
Penghasilan semula masalahVersi MySQL ialah Andaikan terdapat dua jadual 5.7
dan account
struktur adalah seperti berikut: old_account
CREATE TABLE `old_account` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id', `name` varchar(255) DEFAULT NULL COMMENT '账户名', `balance` int(11) DEFAULT NULL COMMENT '余额', `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), KEY `idx_name` (`name`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='老的账户表'; CREATE TABLE `account` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id', `name` varchar(255) DEFAULT NULL COMMENT '账户名', `balance` int(11) DEFAULT NULL COMMENT '余额', `create_time` datetime NOT NULL COMMENT '创建时间', `update_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), KEY `idx_name` (`name`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=1570068 DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT COMMENT='账户表';Mari jelaskan rancangan pelaksanaan dan dapatkan hasil daripada
delete from account where name in (select name from old_account);
Boleh didapati bahawa: mula-mula
imbas seluruh jadual explain
, dan kemudian laksanakan subkueri baris demi baris untuk menentukan sama ada syarat dipenuhi, jelas sekali, pelan pelaksanaan ini tidak memenuhi jangkaan kami, kerana tidak menggunakan indeks . account
Tetapi jika anda menggantikan dengan
delete
select
Mengapakah subkueri pilih dalam
melalui indeks, tetapi pemadaman dalam subkueri tidak melalui indeks?Analisis Sebab
pernyataan subkueri? select in
delete in
Mari laksanakan SQL berikut untuk melihat
explain select * from account where name in (select name from old_account); show WARNINGS;
tunjukkan AMARANpilih `test2`.`account`.`id` AS `id`,`test2`.`account`.`name` AS `name`,` test2`.` account`.`balance` AS `balance`,`test2`.`account`.`create_time` AS `create_time`,`test2`.`account`.`update_time` AS `update_time` daripada `test2` .`akaun`Anda boleh melihat sql yang dilaksanakan akhir selepas pengoptimuman
Keputusan adalah seperti berikut:
separuh sertai (`test2`.`old_account`)pilih dalam subkueridi mana (`test2`.`account`.`name` = `test2`.`old_account`.`name`)
Dapat didapati bahawa semasa pelaksanaan sebenar, MySQL mengoptimumkan
dan menukar subkueri kepada kaedah gabungan, supaya indeks boleh digunakan. Tetapi malangnya, MySQL tidak mengoptimumkannya untuk padam dalam subquery . Pelan pengoptimuman
. Selepas kita menukar kepada kaedah gabungan, mari kita jelaskan sekali lagi:
Kita dapati bahawa kaedah gabungan ialah
yang boleh diindeks, yang merupakan kaedah yang sempurna penyelesaian menyelesaikan masalah ini. Malah, untuk mengemas kini atau memadam kenyataan subquery,
Tapak web rasmi MySQLjuga mengesyorkan kaedah sertai untuk mengoptimumkan
Malah, Menambah alias pada jadual juga boleh menyelesaikan masalah ini, seperti berikut:
explain delete a from account as a where a.name in (select name from old_account)
Mengapa menambah alias boleh mendayakan pengindeksan?
apa? Mengapakah mungkin untuk menambah alias, memadam dalam subquery, dan menggunakan indeks sekali lagi? Mari kita lihat kembali rancangan pelaksanaan explain, dan kita dapat melihat bahawa dalam lajur Tambahan, terdapat
LooseScan.
Apakah itu LooseScan?Sebenarnya, ia adalah strategi, strategi pelaksanaan subkueri separuh sertai. Oleh kerana subkueri ditukar untuk bergabung, pemadaman dalam subkueri boleh diindeks
menambah aliasakan menggunakan strategi LooseScan, dan pada dasarnya strategi LooseScan ialah Ia; ialah strategi pelaksanaan subkueri separuh sertai . Oleh itu, menambah alias membenarkan pemadaman dalam subquery diindeks!
Pembelajaran yang disyorkan:
tutorial video mysqlAtas ialah kandungan terperinci Analisis masalah yang memadam dalam subquery tidak pergi ke indeks dalam mysql. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!