简体   繁体   中英

what's wrong in my sql with a simple self-join query?

I have a table comment ,table column as the follow:

  `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',

I have an index on parent_id column, but when I select data using left join on parent_id, the index does not work in. Is there anything wrong?

The Sql as the follow:

select * from comment p left join comment sub on p.comment_id = sub.parent_id

The explain result:

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)

UPDATE:

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;

And there are 126717 records.

There are several possible reasons what an index on parent_id would not be getting used in your query. One reason is that your comment table is fairly small, in which case MySQL might eschew the use of any index and decide to just scan the table.

Another reason for the index on parent_id not being used is that your query is doing a SELECT * . That is, it is selecting all columns from both tables in the query (which happens to be the same table). Your index covers the join, but not the select. You could consider an index which covers all columns:

CREATE INDEX idx_new ON comment (parent_id, comment_id, comment_content,
                                 nick_name, active_flag);

This index would cover the entire self join to the same table.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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