优化“JOIN”查询

时间:2014-08-22 18:12:24

标签: mysql sql

这是我的源代码

的查询
SELECT `truyen`.*, MAX(chapter.chapter) AS last_chapter
FROM (`truyen`)
LEFT JOIN `chapter` ON `chapter`.`truyen` = `truyen`.`Id`
WHERE `truyen`.`title` LIKE \'%%\'
GROUP BY `truyen`.`Id`
LIMIT 250

当我在iFastnet主机上安装它时,由于连接导致超过500,000行被检查,并且查询被阻止(这将占用超过100%的CPU,最终会导致服务器不稳定)。
我也尝试在查询之前添加此行,它修复了上面的问题,但导致另一个问题使得某些功能无法正常运行

mysql_query("SET SQL_BIG_SELECTS=1");

如何在不购买其他主机的情况下解决此问题?
感谢。

2 个答案:

答案 0 :(得分:0)

您可能正在寻找内部联接。这将删除不匹配的结果。我发现INNER JOIN比LEFT JOIN更快。

但是,我不确定您实际需要的结果。但是因为你正在使用GROUP BY,看起来INNER JOIN可能适合你。

我建议的一件事是将它生成的查询复制并粘贴到带有DESCRIBE的SQL中。

因此,如果查询最终成为:

SELECT truyen.*, MAX(chapter.chapter) AS last_chapter FROM truyen
    LEFT JOIN chapter ON chapter.truyen = truyen.Id
    WHERE truyen.title LIKE '%queryString%'

您可以输入:

DESCRIBE SELECT truyen.*, MAX(chapter.chapter) AS last_chapter FROM truyen
    LEFT JOIN chapter ON chapter.truyen = truyen.Id
    WHERE truyen.title LIKE '%queryString%'

这将告诉您是否可以在表格中添加索引以更快地加入。

我希望这至少可以指出你正确的方向。

Michael Berkowski似乎同意索引,您可以从DESCRIBE中看到。

答案 1 :(得分:0)

请查看chapter.chapter和chapter.truyen上是否有索引。如果没有,请设置它们并重试。如果这不成功,请尝试以下建议:

您是否有可能在插入/更新章节表的列中的最后一章时永久标记?然后你可以使用它来减少连接的行,你可以删除GROUP BY。也许这样:

SELECT `truyen`.*, `chapter`.`chapter` as `last_chapter`
FROM `truyen`, `chapter`
WHERE `chapter`.`truyen` = `truyen`.`Id`
AND `chapter`.`flag_last_chapter` = 1
AND `truyen`.`title` LIKE '%queryString%'
LIMIT 250

或者为此创建一个新表:

INSERT INTO new_table (truyen, last_chapter)
SELECT truyen, MAX(chapter) FROM chapter GROUP BY truyen;

SELECT `truyen`.*, `new_table`.`last_chapter`
FROM (`truyen`)
LEFT JOIN `new_table` ON `new_table`.`truyen` = `truyen`.`Id`
WHERE `truyen`.`title` LIKE '%queryString%'
GROUP BY `truyen`.`Id`
LIMIT 250

否则你可以只获取250行truyen,在数组中收集你的truyen id并构建另一个SQL语句来选择章节表的250行。我在你原来的问题中看到你可以使用PHP。所以你可以在那之后合并结果:

SELECT * FROM truyen
WHERE title LIKE '%queryString%'
LIMIT 250

SELECT truyen, MAX(chapter) AS last_chapter
FROM chapter
WHERE truyen in (comma_separated_ids_from_first_select)