簡體   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