我使用的是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_translation
和category_translation
。我们得到属于旅行的地点和属于城市的地点(这是一个嵌套集合,所以root_id
、lft
和rgt
)
这些索引是:
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
那么,根据你的经验,你会如何改进它,使它变得更小?我知道在我遇到问题之前,我不需要去规范化;但我想修复一个好的基础。
谢谢!
发布于 2009-10-25 18:13:08
有两件事是显而易见的。由于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)
上添加一个索引(所有索引都作为单个索引,而不是每列单独)。
https://stackoverflow.com/questions/1620458
复制相似问题