[英]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.