我们在每张桌子上测试了100万条记录,结果很好,总是低于0,08。 所以我们在我们的服务器上实现了,但它在那里非常慢,最多需要36秒。
我们在优化我们在测试机器上运行的查询之前已经请求了帮助,我们详细介绍了我们的一对多关系的基本结构: Problems to optimize large query and tables structure
这是最终查询,我们在获得上述链接的帮助后使用的那个:
explain SELECT st.sid, st.title, st.summary, st.storynotes, st.thumb, st.completed, st.wordcount, st.rid, st.date, st.updated, stats.total_reviews, stats.total_recommendations, (SELECT GROUP_CONCAT(CAST(catid AS CHAR)) FROM fanfiction_stories_categories WHERE sid = st.sid) as categories, (SELECT GROUP_CONCAT(CAST(genre_id AS CHAR)) FROM fanfiction_stories_genres WHERE sid = st.sid) as genres, (SELECT GROUP_CONCAT(CAST(warning_id AS CHAR)) FROM fanfiction_stories_warnings WHERE sid = st.sid) as warnings FROM fanfiction_stories st LEFT JOIN fanfiction_stories_stats stats ON st.sid = stats.sid JOIN fanfiction_stories_categories cat ON st.sid = cat.sid AND cat.catid = 924 WHERE validated = 1 ORDER BY updated DESC LIMIT 0, 15
这就是解释:
http://dl.dropbox.com/u/14508898/Printscreen/stackoverflow_explain_print_003.PNG
影响0行,找到6行。 1次查询的持续时间:31,356秒
更新
我们在fanfiction_stories中删除了以前数据库结构的一些旧索引,并为fanfiction_stories_categories添加了新索引,现在速度要快得多。这是更新的解释:
http://dl.dropbox.com/u/14508898/Printscreen/stackoverflow_explain_print_004.PNG
抱歉,我使用的程序只将解释表格式化为HTML,CSV等,不会在此处显示ASCII表。
我们可以进一步优化它吗?非常感谢任何帮助。
答案 0 :(得分:0)
您可以使用明确的INNER JOIN代替JOIN,而不是JOIN:
它可能也是您正在做的所有GROUP_CONCAT,它们非常耗费内存。
SELECT
st.sid, st.title, st.summary, st.storynotes, st.thumb, st.completed, st.wordcount, st.rid, st.date, st.updated,
stats.total_reviews, stats.total_recommendations,
(SELECT GROUP_CONCAT(CAST(catid AS CHAR)) FROM fanfiction_stories_categories WHERE sid = st.sid) as categories,
(SELECT GROUP_CONCAT(CAST(genre_id AS CHAR)) FROM fanfiction_stories_genres WHERE sid = st.sid) as genres,
(SELECT GROUP_CONCAT(CAST(warning_id AS CHAR)) FROM fanfiction_stories_warnings WHERE sid = st.sid) as warnings
FROM
fanfiction_stories st
LEFT JOIN fanfiction_stories_stats stats ON st.sid = stats.sid
INNER JOIN fanfiction_stories_categories cat ON st.sid = cat.sid AND cat.catid = 924
WHERE validated = 1
ORDER BY updated DESC
LIMIT 0, 15
答案 1 :(得分:0)
虽然我没有表结构和样本数据来模拟,但这应该可行。通过删除每个(SELECT ...)作为列并只留下左连接,通过sid对整个外部查询进行分组应该给出相同的结果。我认为它比每个子查询AS列比普通查询/连接更有效。无论如何,Group_Concat都根据末尾的“sid”进行分组,并且应该保留......唯一可能是问题的是这些concat字段末尾的任何NULL值,然后可以用IFNULL()测试进行换行。
我会确保这些表中的每一个都有用于连接的“sid”的索引。此外,您的主要故事表的条件为Validated for criteria = 1。
根据您的反馈,我会按照类别将标准和第一个表格移到顶部。首先获取一个类别,然后查看与之关联的故事。然后,仅从那些故事中,连接其余的类型,警告,评论等。你显然有一组较小的类别,所以我会把它作为查询中的主表。让我知道这是如何工作的。
SELECT STRAIGHT_JOIN
st.sid,
st.title,
st.summary,
st.storynotes,
st.thumb,
st.completed,
st.wordcount,
st.rid,
st.date,
st.updated,
stats.total_reviews,
stats.total_recommendations,
GROUP_CONCAT( DISTINCT cat.catid ) categories,
GROUP_CONCAT( DISTINCT genre.genre_id ) genres,
GROUP_CONCAT( DISTINCT warn.warning_id ) as warnings
FROM
fanfiction_stories_categories cat
JOIN fanfiction_stories st
ON cat.sid = st.sid
AND st.Validated = 1
LEFT JOIN fanfiction_stories_stats stats
ON st.sid = stats.sid
LEFT JOIN fanfiction_stories_genres genre
on st.sid = genre.sid
LEFT JOIN fanfiction_stories_warnings warn
on st.sid = warn.sid
WHERE
cat.catid = 924
group by
st.sid
ORDER BY
updated DESC
LIMIT
0, 15