[英]what's wrong in my sql with a simple self-join query?
我有一个表格comment
,表格列如下:
`comment_id` bigint(20) NOT NULL AUTO_INCREMENT,
`nick_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
`comment_content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT 'content',
`parent_id` bigint(20) NULL DEFAULT NULL COMMENT 'parentCommentId',
`active_flag` tinyint(4) NOT NULL DEFAULT 0 COMMENT 'activeFlag',
我在 parent_id 列上有一个索引,但是当我在 parent_id 上使用左连接 select 数据时,索引不起作用。有什么问题吗?
Sql 如下:
select * from comment p left join comment sub on p.comment_id = sub.parent_id
解释结果:
mysql> EXPLAIN select * from comment p left join comment sub on p.comment_id = sub.parent_id;
+----+-------------+-------+------------+------+------------------+------+---------+------+--------+----------+----------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+------------------+------+---------+------+--------+----------+----------------------------------------------------+
| 1 | SIMPLE | p | NULL | ALL | NULL | NULL | NULL | NULL | 126717 | 100.00 | NULL |
| 1 | SIMPLE | sub | NULL | ALL | comment_n2 | NULL | NULL | NULL | 126717 | 100.00 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------------+------+------------------+------+---------+------+--------+----------+----------------------------------------------------+
2 rows in set (0.03 sec)
更新:
CREATE TABLE `comment` (
`comment_id` bigint(20) NOT NULL AUTO_INCREMENT,
`catalog_version_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '',
`nick_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
`login_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
`user_id` bigint(20) NOT NULL COMMENT '',
`operated_id` bigint(20) NULL DEFAULT NULL COMMENT '',
`comment_type_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '',
`level_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '',
`comment_content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '本',
`average_comment_score` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '',
`describe_score` int(11) NULL DEFAULT NULL COMMENT '',
`logistics_score` int(11) NULL DEFAULT NULL COMMENT '',
`service_score` int(11) NULL DEFAULT NULL COMMENT '',
`comment_status_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '',
`platform_order_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '',
`platform_order_entry_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '',
`parent_id` bigint(20) NULL DEFAULT NULL COMMENT '',
`tenant_id` bigint(20) NOT NULL DEFAULT 0,
`object_version_number` bigint(20) NOT NULL DEFAULT 1,
`creation_date` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
`created_by` bigint(20) NOT NULL DEFAULT -1,
`last_updated_by` bigint(20) NOT NULL DEFAULT 1,
`last_update_date` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
`reply_flag` tinyint(4) NULL DEFAULT NULL COMMENT '',
`active_flag` tinyint(4) NOT NULL DEFAULT 0 COMMENT '',
`display_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
`operated_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
`platform_product_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '',
`platform_sku_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '',
`sku_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '',
PRIMARY KEY (`comment_id`) USING BTREE,
UNIQUE INDEX `comment_u1`(`comment_id`, `tenant_id`) USING BTREE,
INDEX `comment_n1`(`platform_product_code`, `platform_sku_code`, `tenant_id`) USING BTREE,
INDEX `comment_n2`(`parent_id`, `tenant_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 128596 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
并且有126717条记录。
查询中未使用parent_id
上的索引有几个可能的原因。 一个原因是您的comment
表相当小,在这种情况下 MySQL 可能会避免使用任何索引并决定只扫描表。
未使用parent_id
索引的另一个原因是您的查询正在执行SELECT *
。 也就是说,它从查询中的两个表中选择所有列(恰好是同一个表)。 您的索引涵盖连接,但不包括 select。 您可以考虑一个涵盖所有列的索引:
CREATE INDEX idx_new ON comment (parent_id, comment_id, comment_content,
nick_name, active_flag);
该索引将覆盖同一张表的整个自连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.