NL连接一定是小表驱动大表效率高吗

  • GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
  • GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。
  • 作者: JennyYu
  • 文章来源:GreatSQL社区原创

前言

两表使用nest loop(以下简称NL)方式进行连接,小表驱动大表效率高,这似乎是大家的共识,但事实上这是有条件的,并不总是成立。这主要看大表扫描关联字段索引后返回多少数据量,是否需要回表,如果大表关联后返回大量数据,然后再回表,这个代价就会很高,大表处于被驱动表的位置可能就不是最佳选择了。

实验举例

使用benchmarksql压测的两个表bmsql_warehousebmsql_order_line来测试,初始化10仓数据。

mysql> show create table bmsql_warehouse\G *************************** 1. row *************************** Table: bmsql_warehouse Create Table: CREATE TABLE `bmsql_warehouse` ( `w_id` int NOT NULL, `w_ytd` decimal(12,2) DEFAULT NULL, `w_tax` decimal(4,4) DEFAULT NULL, `w_name` varchar(10) DEFAULT NULL, `w_street_1` varchar(20) DEFAULT NULL, `w_street_2` varchar(20) DEFAULT NULL, `w_city` varchar(20) DEFAULT NULL, `w_state` char(2) DEFAULT NULL, `w_zip` char(9) DEFAULT NULL, PRIMARY KEY (`w_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci mysql> show create table bmsql_order_line\G *************************** 1. row *************************** Table: bmsql_order_line Create Table: CREATE TABLE `bmsql_order_line` ( `ol_w_id` int NOT NULL, `ol_d_id` int NOT NULL, `ol_o_id` int NOT NULL, `ol_number` int NOT NULL, `ol_i_id` int NOT NULL, `ol_delivery_d` timestamp NULL DEFAULT NULL, `ol_amount` decimal(6,2) DEFAULT NULL, `ol_supply_w_id` int DEFAULT NULL, `ol_quantity` int DEFAULT NULL, `ol_dist_info` char(24) DEFAULT NULL, PRIMARY KEY (`ol_w_id`,`ol_d_id`,`ol_o_id`,`ol_number`), KEY `ol_stock_fkey` (`ol_supply_w_id`,`ol_i_id`), KEY `ol_d_id` (`ol_d_id`), CONSTRAINT `ol_order_fkey` FOREIGN KEY (`ol_w_id`, `ol_d_id`, `ol_o_id`) REFERENCES `bmsql_oorder` (`o_w_id`, `o_d_id`, `o_id`), CONSTRAINT `ol_stock_fkey` FOREIGN KEY (`ol_supply_w_id`, `ol_i_id`) REFERENCES `bmsql_stock` (`s_w_id`, `s_i_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci