首页 > 解决方案 > 加入“2列”非常慢

问题描述

我有 2 张桌子,我需要INNER JOIN on 2 equal columns这样:

SELECT
    `table1`.*
FROM
    `table1`
    INNER JOIN `table2`
        ON  `table2`.`type` = `table1`.`type`
        AND `table2`.`num`  = `table1`.`num`
WHERE
    `table2`.`another_int` = 1
ORDER BY
    `table1`.`id` DESC
LIMIT 10 OFFSET 0

当我尝试时,查询需要1500ms

但是删除 2 个 JOIN 条件中的任何一个,或删除ORDER BY将导致查询在1ms


更多信息:


使用EXPLAIN:两个表都使用键,但额外列显示表 2:“使用索引;使用临时;使用文件排序”

删除 WHERE 条件或 LIMIT OFFSET 没有效果,但我刚刚注意到,删除ORDER BY同时保持 LIMIT 会导致查询在不到 1ms 的时间内运行

不知道这里有什么问题或我应该做什么,所以任何帮助表示赞赏......

编辑

/* Table 1 Keys */

KEY `posts_user_id_foreign` (`user_id`),
KEY `posts_composite_ind` (`post_followable_type`,`post_followable_id`,`id`) USING BTREE,
CONSTRAINT `posts_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=456501 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


/* Table 2 Keys */

PRIMARY KEY (`id`),
UNIQUE KEY `unique_user_follows` (`user_id`,`followable_type`,`followable_id`),
CONSTRAINT `follows_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1525 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

/* Query */
SELECT
`posts`.*, `follows`.`user_id` AS `current_user`
FROM
`posts`
INNER JOIN `follows` 
    ON `follows`.`followable_type` = `post_followable_type`
    AND `follows`.`followable_id` = `post_followable_id`
WHERE
    `follows`.`user_id` = 1
ORDER BY
    `posts`.`id` DESC
LIMIT 11 OFFSET 0


/* Explain */

| id | select_type | table   | partitions | type | possible_keys       | key                 | key_len | ref                                                 | rows | filtered | Extra                                        |
|----|-------------|---------|------------|------|---------------------|---------------------|---------|-----------------------------------------------------|------|----------|----------------------------------------------|
|  1 | SIMPLE      | follows |            | ref  | unique_user_follows | unique_user_follows | 8       | const                                               |  511 |   100.00 | Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | posts   |            | ref  | posts_composite_ind | posts_composite_ind | 9       | db.follows.followable_type,db.follows.followable_id |  453 |   100.00 |                                              |

/* End */

标签: mysql

解决方案


表2需要INDEX(another_int, num, type)another_int必须是第一。但我猜你有。

摆脱follows.id和提升的UNIQUE关键是PRIMARY KEY

table1 需要INDEX(num, type);列可以按任意顺序排列。好的,我看到你有这样的索引。无需更改。


推荐阅读