我有一个包含三个相关表的 MySQL 数据库,t1 有 6598 行,t2 有 1713 行和 t3 有 10023 行。
详细信息:
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
里面的记录没有限制,我们不妨先扫这个。然后,对于 t1
和 t3
的每个连接,我们尝试使用索引设置。请注意,由于您的表的列数相对较少,因此定义的两个索引可以轻松覆盖所有列,从而增加 MySQL 选择使用索引的可能性。
关于mysql - 使用多个内部连接和顺序子句时 sql 查询速度极慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56968831/