【问题标题】:Improve this possible 5 joins SQL sentence改进这个可能的 5 join SQL 语句
【发布时间】:2009-10-25 09:27:27
【问题描述】:

我用的是MySQL 5,需要做这句话才能得到结果。当我想到它时,这是第一次尝试。我知道有几种方法可以改进它,但我想先征求您的意见:

SELECT p.id, p.image, p.lat, p.lng, 
       p.category_id, p2.title, p2.description, c2.name
FROM place p
LEFT JOIN place_translation p2 ON p.id = p2.id
LEFT JOIN trip_place t ON p.id = t.place_id
LEFT JOIN category c ON p.category_id = c.id
LEFT JOIN category_translation c2 ON c.id = c2.id
WHERE c.root_id =1
AND c2.lang =  'en'
AND p2.lang =  'en'
AND t.trip_id =1
AND p.root_id =1
AND p.lft >39
AND p.rgt <44
ORDER BY p2.title

这是一项多语言服务,所以我们有place_translationcategory_translation。我们得到属于旅行和城市的地方(这是一个嵌套集,所以root_idlftrgt

索引是:

on table place: id, category_id
on table place_translation: id-lang index
on table trip_place: place_id, trip_id
on table category: id
on table category_translation: id-lang index

那么,根据您的经验,您将如何改进它以使其更小?我知道在遇到问题之前我不必进行非规范化;但我想打好基础。

谢谢!

【问题讨论】:

  • 您在各个表上有哪些索引?
  • 桌子上的地方:id,桌子上的类别_翻译:桌子上的id-lang索引trip_place:place_id,桌子上的trip_id类别:桌子上的id category_translation:id-lang索引
  • @fesja:建议您使用索引信息编辑问题...

标签: sql mysql performance join


【解决方案1】:

有两件显而易见的事情。由于您对WHERE 中每个表的值都有条件,因此您需要在JOIN 子句中找到匹配的行。这意味着您应该使用内连接,而不是左外连接。接下来,为了尽快过滤结果,您可以将一些条件从WHERE 移动到JOIN .. ON

我还以对我来说有意义的方式重新排列了表格,即首先您从 trip_place 中选择,因为您知道您只想要这次旅行的地点。然后为trip_place 中的每一行找到匹配的place,并为每个place 找到匹配的category。翻译是最后的,因为它们在功能上不会影响查询。所以查询会是这样的:

SELECT
    p.id, p.image, p.lat, p.lng, 
    p.category_id, p2.title, p2.description, c2.name
FROM
    trip_place t
    JOIN place p ON p.id = t.place_id AND p.root_id = 1 AND p.lft > 39 AND p.rgt < 44
    JOIN category c ON p.category_id = c.id AND c.root_id = 1
    JOIN place_translation p2 ON p.id = p2.id AND p2.lang = 'en'
    JOIN category_translation c2 ON c.id = c2.id AND c2.lang = 'en'
WHERE
    t.trip_id = 1
ORDER BY p2.title

我不知道它是否真的更快,但它可能是。你应该在他们两个上运行EXPLAIN。从索引列表来看,您可能应该在place (root_id, p.lft, p.rgt) 上添加一个索引(所有这些都作为一个索引,而不是单独的每一列)。

【讨论】:

  • 感谢 Lukáš,我已经添加了您告诉我的索引和类别中的另一个索引:root_id 您的句子花费的时间要少一些(0.0018 对 0.0020),但它更有意义。所以我想当我有数千行时,差异会更大,谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-08-02
  • 2016-05-02
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多