多对一优化mysql选择查询

Posted

技术标签:

【中文标题】多对一优化mysql选择查询【英文标题】:optimize mysql select query on many to one 【发布时间】:2011-08-16 12:22:26 【问题描述】:

我正在尝试优化 mysql 选择查询,但我不知道该怎么做。

我一直在这里阅读和谷歌上的任何其他相关结果,但找不到任何有我问题的人,希望这不是因为我构建了非常糟糕的数据库表

我有三个表,表A,表B,表C

表A和表B是一对一的关系

表A与表C是一对多的关系

因为我需要表 c 中与表 A 中的每一行相关的所有信息,所以我使用 GROUP BY 将结果浓缩为表 A 中相关结果的数量。

不幸的是,当添加 GROUP BY 时,它会导致 mysql 创建一个临时表,这会减慢一切。

我已经阅读了 mysql 在哪些实例中将使用临时表,似乎我应该能够使其工作,但无法弄清楚如何做到这一点,我希望我可以用结果相同,但没有 tmp 表,这使它变慢。

我的查询中还有一个订单。如果我删除 GROUP BY,我会得到表 A 中的所有行以及表 C 的累积结果,但它会在几分之一秒内完成所有这些。

使用 GROUP BY 和使用或不使用 ORDER BY,因为 mysql 然后使用 tmp 表,它需要 2 到 15 秒,具体取决于所需的任何其他条件。

这基本上是我的查询(尽管出于安全原因更改了详细信息)

SELECT 
table_a.*, table_b.*, table_c.*
FROM `table_a` 
LEFT JOIN table_b ON table_b.ID = table_a.table_b_id 
LEFT JOIN table_c ON table_a.ID = table_c.table_a_id AND table_c.deleted !='yes' 
WHERE table_a.deleted !='yes' AND table_b.deleted !='yes' 
GROUP BY table_a.ID 
ORDER BY table_a.date_added DESC

我在表 a 中有大约 15k 个结果,在表 c 中有 100k 个结果

我真的需要表 c 中与表 a 中的行相关的所有信息,所以我的想法是如果

一个。我可以删除 group by 并完成相同的最终结果,然后它将不再需要 tmp 表并加快速度 湾。改变我将表连接在一起的方式,以便对分组结果的排序更有效,然后希望也删除 tmp 表

我可以让这个查询更有效率,还是因为我的表的设置方式而卡住了?


感谢您的回复。

对不起,我应该提到我已经尝试 group by 和 order 与 table_a.ID 的值相同,但是从 mysql EXPLAIN 来看,这似乎仍在使用 tmp 表。

从测试看来,删除 order by 并仅使用 group by 仍然不起作用,尽管 order by 本身很好,它只是带回了所有结果。

不过,在执行 EXPLAIN 时,我注意到 table_a 的 possible_keys 和 key 都为 null,即使 table_b 和 table_c 都在使用可能的 key 和 key 的列进行报告。

我是否应该从 EXPLAIN 中获得 table_a 有密钥的指示?

马特


对不起,它来自 phpmyadmin,所以不是最好的布局。

id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE table_a ALL NULL NULL NULL NULL 13297 使用where;使用临时的;使用文件排序 1 SIMPLE table_b eq_ref PRIMARY,ID, PRIMARY 3 db.table_a.table_b_id 1 使用 where 1 SIMPLE table_c ref table_a_id table_a_id 3 db.table_a.ID 9

【问题讨论】:

请将 EXPLAIN 的结果添加到问题中 【参考方案1】:

当您使用不同字段的 GROUP BY 和 ORDER BY 时,您几乎总是会得到一个临时表。

附带说明,由于包含所有字段但仅按 table_a.ID 分组,您的选择可能会产生意外结果。表 C 中的记录可能会被破坏。

【讨论】:

以上是关于多对一优化mysql选择查询的主要内容,如果未能解决你的问题,请参考以下文章

MySQL学习笔记-多表查询(上)

mysql表的一对一/一对多/多对多联系

关联查询 一对多,多对一,多对多,自关联

laravel ORM 一对一 一对多 多对多 原生的MYSQL怎么写

MVC LINQ 查询以使用一对多和多对一表填充模型

Mybatis多表查询(一对多,多对一,多对多)