MySQL中的回表指的是在查詢語句中使用了索引,在查詢過程中需要再次查找非索引列的數據。例如,下面這個查詢語句中的age列使用了索引:
SELECT name FROM user WHERE age = 25;
在查詢時,MySQL會先根據age列的索引找到符合條件的行,然后再到原表中找到name列的數據。這個過程就需要回表。
但是,當回表的次數過多時,會導致索引失效,從而導致查詢效率的下降。
下面通過一個例子來說明:
CREATE TABLE `orders` ( `order_id` bigint(20) NOT NULL AUTO_INCREMENT, `product_id` bigint(20) NOT NULL, `user_id` bigint(20) NOT NULL, `status` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL, `created_time` datetime NOT NULL, PRIMARY KEY (`order_id`), KEY `product_id_idx` (`product_id`), KEY `user_id_idx` (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
在這個表中,我們有一個訂單表,其中product_id和user_id都建立了索引。現在我們需要查詢某個用戶的所有訂單:
SELECT * FROM orders WHERE user_id = 1;
這個查詢語句使用了user_id的索引,因此查詢效率較高。但是,如果我們需要查詢某個用戶的訂單的詳細商品信息:
SELECT orders.*, products.* FROM orders LEFT JOIN products ON orders.product_id = products.product_id WHERE orders.user_id = 1;
這個查詢語句使用了LEFT JOIN關鍵字,需要將訂單表和商品表進行關聯查詢。這個過程中,MySQL需要回表兩次,一次是查找訂單的詳細信息,一次是查找商品的詳細信息。
這種情況下,我們可以通過添加聯合索引來提高查詢效率:
ALTER TABLE `orders` ADD INDEX `user_product_idx` (`user_id`,`product_id`);
添加聯合索引之后,回表的次數就從2次降到了1次,查詢效率提高了很多。