mysql - 使用多个内部连接和顺序子句时 sql 查询速度极慢

标签 mysql query-optimization

我有一个包含三个相关表的 MySQL 数据库,t16598 行,t21713 行和 t310023 行。

详细信息:

TABLE t1 (
    `id` SERIAL,
    `t2_id` BIGINT UNSIGNED NOT NULL,
    `t3_id` BIGINT UNSIGNED,
    PRIMARY KEY (`id`),
    FOREIGN KEY (t2_id) REFERENCES t2(id),
    FOREIGN KEY (t3_id) REFERENCES t3(id)   
);

TABLE t2(
    `id` SERIAL,
    `name` VARCHAR(128) NOT NULL,
    PRIMARY KEY (`id`)
);

TABLE t3 (
    `id` SERIAL,
    `name` VARCHAR(128),
    PRIMARY KEY (`id`)
);

我想执行以下查询但它没有完成(基本上永远需要):

SELECT *
FROM t1
INNER JOIN t3
ON t1.t3_id = t3.id
INNER JOIN t2
ON t1.t2_id = t2.id
WHERE (t3.name NOT NULL)
ORDER BY t3.name ASC , t1.id ASC
LIMIT 25

当我删除 order 子句时,它的运行速度非常快(0.17 秒)。

我如何更改查询以使其工作?

最佳答案

我可以建议以下指标:

CREATE INDEX idx_t1 ON t1 (t2_id, t3_id, id);
CREATE INDEX idx_t3 ON t3 (id, name);

这些索引至少应该大大加快连接速度。如果使用,MySQL 很可能会采用以下连接策略:

SELECT *
FROM t2
INNER JOIN t1
    ON t2.id = t1.t2_id
INNER JOIN t3
    ON t1.t3_id = t3.id
WHERE
    t3.name IS NOT NULL
ORDER BY
    t3.name,
    t1.id
LIMIT 25;

这里的想法是我们对 t2 进行全表扫描,这是迄今为止最小的表。反正t2里面的记录没有限制,我们不妨先扫这个。然后,对于 t1t3 的每个连接,我们尝试使用索引设置。请注意,由于您的表的列数相对较少,因此定义的两个索引可以轻松覆盖所有列,从而增加 MySQL 选择使用索引的可能性。

关于mysql - 使用多个内部连接和顺序子句时 sql 查询速度极慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56968831/

相关文章:

php - 对于laravel多态多态关系,如何添加数据库约束?

sql - 使用 3 个 FOR 循环优化 SQL 查询

mysql - 尝试通过在MySQL中添加索引来改善慢查询

php - 如何在排序列中添加 +1

php - 使用 PHP 进行实时更新和邮件

php - Laravel - 带有未签名主键的表迁移错误

mysql - MySQL中的批量替换字符串

MySQL - 基本的 2 表查询速度慢 - 索引在哪里?

mysql - 优化sql中以下查询时间

mysql - 如何编写优化的 MySQL 搜索文本查询,替代 OR