我正在编写一个效果很好的查询,但速度非常慢。我真的不知道如何进一步加快速度。我没有看到任何可以设置的索引,也没有任何方法可以更改查询以加快速度而不会破坏它。
关于数据结构:我有对象,可以属于房间,公寓或楼层。一个房间总是属于一个公寓,一个公寓总是属于一个楼层。听起来很复杂,但事实并非如此,这就是层次结构:
这是我目前的查询:
SELECT
whatever
FROM Object AS o
LEFT JOIN Room AS r AS r.id = o.Room_id
LEFT JOIN Apartment AS a
ON a.id = o.Apartment_id
OR a.id = r.Apartment_id
LEFT JOIN Floor AS f
ON f.id = o.Floor_id
OR f.id = r.Floor_id
OR f.id = a.Floor_id
JOIN Building AS b ON b.id = f.Building_id
/* some conditions concerning the Building */
此查询大约需要17秒。可接受的是< .2s,所以它的方式,减缓的方式。
答案 0 :(得分:0)
如果没有样本数据和预期输出,我无法确定,但根据您的数据,以下内容应该足够了。
SELECT *
FROM Building b
INNER JOIN Floor f ON b.id = f.Building_id
INNER JOIN Apartment a ON f.id = a.Floor_id
INNER JOIN Room r ON a.id = r.Apartment_id
INNER JOIN Object o ON r.id = o.Room_id
答案 1 :(得分:0)
我会按如下方式查询。将查询构建嵌套到空间作为自然层次结构。在“对象”可能位于楼层,公寓或房间的每个位置,在该特定条件下进行左连接。然后,您的字段列表可以明确地引用不同的别名,以分别在地板,公寓或房间显示它。
不知道你的索引,我建议如下
table index
building (id) -- assume already since it would be PK
floor (building_id, id)
apartment (floor_id, id)
room (apartment_id, id)
对象表,在它可能存在的方面ID上有3个单独的索引
object (floor_id)
object (apartment_id)
object (room_id)
SELECT
b.id as BuildingID,
f.id as FloorID,
COALESCE( FObj.ObjectDescrip, " " ) as FloorObject,
a.id as ApartmentID,
COALESCE( AObj.ObjectDescrip, " " ) as ApartmentObject,
r.id as RoomID,
COALESCE( RObj.ObjectDescrip, " " ) as RoomObject
from
Building b
join floor f
ON b.id = f.building_id
left join object as FObj
ON f.id = FObj.floor_id
left join apartment a
ON f.id = a.floor_id
left join object as AObj
ON a.id = AObj.apartment_id
left join room r
ON a.id = r.apartment_id
left join object as RObj
ON r.id = RObj.room_id
由于您似乎担心每个建筑物,地板,公寓和房间的完整性,所以无论实际物体位于任何一个可能的位置,这都应该适合您。
答案 2 :(得分:0)
检查这是否表现更好。
SELECT
b.id as Building_id,
f.id as Floar_id,
a.id as Apartment_id,
r.id as Room_id,
COALESE (ro.Description, ao.Description, fo.Description) as Object_Description
FROM Building b
INNER JOIN Floor f ON b.id = f.Building_id
INNER JOIN Apartment a ON f.id = a.Floor_id
INNER JOIN Room r ON a.id = r.Apartment_id
LEFT JOIN Object ro ON r.id = ro.Room_id
LEFT JOIN Object ao on a.id = ao.Apartment_id
LEFT JOIN Object fo on f.id = fo.Floar_id
答案 3 :(得分:0)
我觉得自己从一开始就没有想出这个解决方案。 ON子句中用于加入公寓的简单IF语句为我做了诀窍:
SELECT
whatever
FROM Object AS o
LEFT JOIN Room AS r ON r.id = o.Room_id
LEFT JOIN Apartment AS a
/* This solved it */
ON a.id = IF(o.Apartment_id IS NULL, r.Apartment_id, o.Apartment_id)
LEFT JOIN Floor AS f
ON f.id = o.Floor_id
OR f.id = r.Floor_id
OR f.id = a.Floor_id
JOIN Building AS b ON b.id = f.Building_id
/* some conditions concerning the Building */
感谢您的所有答案!