我正在寻找优化我的SQL。
我的数据库架构是:
“家”很可能没有与家庭相关的照片。在这种情况下,primary_photo_group_id
= 0 . Otherwise,
primary_photo_group_id`等于要用作主要照片的照片的group_id。
SELECT homes.home_id,
address,
city,
state,
zip,
photo_id,
photo_url_dir
FROM homes, home_photos
WHERE homes.home_id = home_photos.home_id
AND primary_photo_group_id = home_photo_group_id
AND home_photo_type_id = 2
UNION
SELECT homes.home_id,
address,
city,
state,
zip,
null,
null
FROM homes
WHERE primary_photo_group_id = 0
我想摆脱UNION,因为我不得不在整个桌子上搜索2x。我如何摆脱UNION,因为我需要检查primary_photo_group_id = 0的情况,如果它不等于0,则查询home_photos
表
SELECT homes.home_id,
address,
city,
state,
zip,
photo_id, (include only if primary_photo_group_id != 0)
photo_url_dir (include only if primary_photo_group_id != 0)
FROM homes,
home_photos (include only if primary_photo_group_id != 0)
WHERE
primary_photo_group_id = 0
ELSE
homes.home_id = home_photos.home_id
AND primary_photo_group_id = home_photo_group_id
AND home_photo_type_id = 2
答案 0 :(得分:1)
SELECT homes.home_id,
address,
city,
state,
zip,
photo_id,
photo_url_dir
FROM homes
LEFT JOIN
home_photos
ON home_photos.home_id = homes.home_id
AND home_photo_group_id = CASE WHEN primary_photo_group_id = 0 THEN NULL ELSE primary_photo_group_id END
AND home_photo_type_id = 2
在home_photos (home_id, home_photo_group_id, home_photo_type_id)
上使用综合索引将大大改善此查询。
请注意,即使CASE
中没有0
的记录,使用home_photo_group_id = 0
的效率也会略高于home_photos
上的左侧加入效果。
当MySQL
在JOIN
上看到NULL
时(根据定义不会产生任何结果),它甚至不会查看已连接的表格。当它加入0
时,它仍然必须检查索引并确保不存在任何值。
这对性能影响不大,但仍可以将查询时间提高几个百分点,尤其是0
中有很多homes
时。
请参阅我的博客中的此条目,了解效果详情:
另请注意,您的表格不在2NF
。
您的group_id
取决于home_id
,并将其包含在home_photos
违反2NF
。
这并不总是坏事,但可能更难管理。
答案 1 :(得分:1)
如果第二个查询比第一个查询慢,那是因为您在{home_id, primary_photo_group_id}
(或者只是{home_id}
)上有一个索引,但仅在{primary_photo_group_id}
上没有。如果要提高查找该列的性能,则需要此列的索引。
答案 2 :(得分:0)
了解[加入](http://en.wikipedia.org/wiki/Join_(SQL)
Select * from table_a, table_b
是一个交叉连接 - 您将其限制为带有where子句的内连接。将您的查询转换为内部联接,然后阅读有关外部联接的信息。
编辑:我不只是给你答案,因为我认为这是家庭作业,但我仍然不会只给你答案,因为外连接很重要,甚至可以知道甚至如果您只是为网站编写SQL。你将成为一个更好的学习者,并以此为例。
答案 3 :(得分:0)
也许你不知道左外连接?尝试:
SELECT homes.home_id,
address,
city,
state,
zip,
photo_id
photo_url_dir
FROM homes h
left outer join home_photos hp on h.home_id = hp.home_id
AND primary_photo_group_id = home_photo_group_id
AND home_photo_type_id = 2