繁体   English   中英

使用简单的自联接查询,我的 sql 出了什么问题?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM