MySQL是目前非常流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),廣泛應(yīng)用于各種應(yīng)用場(chǎng)景,如電商、金融、游戲等。在使用MySQL時(shí),回表查詢是一種常見的場(chǎng)景。
回表查詢指的是當(dāng)我們查詢一條記錄時(shí),MySQL首先會(huì)在聚集索引上查找,然后根據(jù)聚集索引中的非聚集索引的指針找到對(duì)應(yīng)的數(shù)據(jù)行,這個(gè)過程就稱為回表查詢。
對(duì)于回表查詢,雖然在單次查詢時(shí)對(duì)性能的影響不大,但是在大數(shù)據(jù)量下,它的性能優(yōu)化是非常重要的,下面我們通過代碼演示,來看一下回表查詢的相關(guān)情況。
-- 創(chuàng)建測(cè)試表 CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, `age` int(11) DEFAULT NULL, `score` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name_index` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; -- 插入測(cè)試數(shù)據(jù) INSERT INTO `student` (`name`, `age`, `score`) VALUES ('小明', 20, 90), ('小紅', 21, 93), ('小李', 23, 95);
我們首先使用explain語(yǔ)句來查看回表查詢的執(zhí)行情況:
EXPLAIN SELECT `id`, `name`, `age`, `score` FROM `student` WHERE `name` = '小明';
執(zhí)行結(jié)果如下:
+----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+-------------+ | 1 | SIMPLE | student | NULL | ref | name_index | name | 153 | const | 1 | 100.00 | Using index | +----+-------------+---------+------------+------+---------------+------+---------+-------+------+----------+-------------+
從結(jié)果可以看出,查詢使用了非聚集索引,沒有使用聚集索引,同時(shí)Extra列中顯示了使用了“Using index”。
如果我們希望在回表查詢時(shí)能夠同時(shí)命中聚集索引和非聚集索引,我們需要?jiǎng)?chuàng)建覆蓋索引,它的定義如下:
ALTER TABLE `student` ADD INDEX `cover_index` (`name`, `age`, `score`) USING BTREE;
然后,我們?cè)俅问褂胑xplain語(yǔ)句來查看查詢執(zhí)行情況:
EXPLAIN SELECT `id`, `name`, `age`, `score` FROM `student` WHERE `name` = '小明';
執(zhí)行結(jié)果如下:
+----+-------------+---------+------------+-------+---------------+--------------+---------+------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+---------+------------+-------+---------------+--------------+---------+------+------+----------+--------------------------+ | 1 | SIMPLE | student | NULL | index | cover_index | cover_index | 158 | NULL | 1 | 100.00 | Using where; Using index | +----+-------------+---------+------------+-------+---------------+--------------+---------+------+------+----------+--------------------------+
從結(jié)果可以看出,查詢使用了索引,同時(shí)使用了“Using where”和“Using index”。
綜上,回表查詢是MySQL常見的查詢場(chǎng)景之一,需要根據(jù)具體情況進(jìn)行性能優(yōu)化,避免潛在的性能瓶頸。