NL连接一定是小表驱动大表效率高吗
- GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
- GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。
- 作者: JennyYu
- 文章来源:GreatSQL社区原创
前言
两表使用nest loop(以下简称NL)方式进行连接,小表驱动大表效率高,这似乎是大家的共识,但事实上这是有条件的,并不总是成立。这主要看大表扫描关联字段索引后返回多少数据量,是否需要回表,如果大表关联后返回大量数据,然后再回表,这个代价就会很高,大表处于被驱动表的位置可能就不是最佳选择了。
实验举例
使用benchmarksql压测的两个表bmsql_warehouse
与bmsql_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