在查询中添加第3个表会减慢结果时间

时间:2016-05-02 07:48:22

标签: mysql optimization

我正在使用一个查询,在一秒钟内给出结果。

查询是,

SELECT creator.first_name, image.id, image.image_code, image.project, image.location, image.image_date, image.image_view, image.copyright 
FROM img_images image, img_creator creator 
WHERE creator.image_id = image.id AND (
(image.image_code LIKE '%text%') 
OR (image.project LIKE '%text%') 
OR (image.location LIKE '%text%')
OR (creator.first_name LIKE '%text%')) 
ORDER BY creator.first_name

现在,如果我在此查询中添加第三个表,则需要大约20到30秒才能给出结果。

查询,

SELECT creator.first_name, image.id, image.image_code, image.project, image.location, image.image_date, image.image_view, image.copyright, sources.author 
FROM img_images image, img_creator creator, img_source sources 
WHERE creator.image_id = image.id AND sources.image_id = image.id AND (
(image.image_code LIKE '%text%') 
OR (image.project LIKE '%text%') 
OR (image.location LIKE '%text%')
OR (creator.first_name LIKE '%text%')) 
ORDER BY creator.first_name

如何优化此查询以快速响应? 所有表格中都有适当的索引。

1 个答案:

答案 0 :(得分:0)

有时在没有过滤条件的表上强制左连接有助于RDBMS选择更好的计划:

SELECT creator.first_name, image.id, image.image_code, image.project, image.location,
       image.image_date, image.image_view, image.copyright, sources.author
FROM img_images image
JOIN img_creator creator ON (creator.image_id = image.id OR creator.first_name LIKE '%text%')
LEFT JOIN img_source sources ON (sources.image_id = image.id)
WHERE image.image_code LIKE '%text%' OR image.project LIKE '%text%' OR image.location LIKE '%text%'
ORDER BY creator.first_name;

此外,当结果集中的行数预计很小,但查询很复杂和/或涉及大表时,我觉得值得为单个值尝试单独查找:

SELECT creator.first_name, image.id, image.image_code, image.project, image.location,
       image.image_date, image.image_view, image.copyright
       (SELECT author FROM img_source WHERE image_id = image.id) AS author
FROM img_images image
JOIN img_creator creator ON (creator.image_id = image.id OR creator.first_name LIKE '%text%')
WHERE image.image_code LIKE '%text%' OR image.project LIKE '%text%' OR image.location LIKE '%text%'
ORDER BY creator.first_name;