SQL:帮我优化我的SQL

时间:2009-06-24 17:27:45

标签: sql mysql database database-design optimization

我正在寻找优化我的SQL。

我的数据库架构是:

  • HOME_ID
  • 地址
  • 城市
  • 状态
  • 拉链
  • primary_photo_group_id

HOME_PHOTOS

  • photo_id(主键)
  • home_id(主要主键)
  • photo_group_id(照片组是相同的图片,从缩略图调整为大尺寸)
  • home_photo_type_id(图片的大小可以是缩略图或大尺寸)
  • photo_url_dir(存储照片的文件系统位置)

问题

“家”很可能没有与家庭相关的照片。在这种情况下,primary_photo_group_id = 0 . Otherwise, primary_photo_group_id`等于要用作主要照片的照片的group_id。

慢速SQL(UNION的b / c)

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

4 个答案:

答案 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上的左侧加入效果。

MySQLJOIN上看到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