我的网站突然开始吐出以下错误:
“表'/tmp/#sql_645a_1.MYI'的密钥文件不正确;尝试修复它”
我删除它,该网站工作正常。
我的服务器技术支持人员建议我清理查询并提高效率。
以下是查询:
SELECT *, FROM_UNIXTIME(post_time, '%Y-%c-%d %H:%i') as posttime
FROM communityposts, communitytopics, communityusers
WHERE communityposts.poster_id=communityusers.user_id
AND communityposts.topic_id=communitytopics.topic_id
ORDER BY post_time DESC LIMIT 5
非常感谢任何帮助。也许可以通过JOIN来完成?
非常感谢,
斯科特
更新:这是工作查询,我仍然觉得它可以优化。
SELECT
communityposts.post_id, communityposts.topic_id, communityposts.post_time,
communityusers.user_id, , communitytopics.topic_title, communityusers.username,
communityusers.user_avatar,
FROM_UNIXTIME(post_time, '%Y-%c-%d %H:%i') as post time
FROM
communityposts,
communitytopics,
communityusers
WHERE
communityposts.poster_id=communityusers.user_id
AND communityposts.topic_id=communitytopics.topic_id
ORDER BY post_time DESC LIMIT 5
答案 0 :(得分:3)
SELECT
A.*,B.*,C.*,FROM_UNIXTIME(post_time, '%Y-%c-%d %H:%i') as posttime
FROM
(
SELECT id,poster_id,topic_id
FROM communityposts
ORDER BY post_time DESC
LIMIT 5
) cpk
INNER JOIN communityposts A USING (id)
INNER JOIN communityusers B ON cpk.poster_id=B.user_id
INNER JOIN communitytopics C USING (topic_id);
如果社区帖子不必拥有用户和主题,则对最后两个联接使用LEFT JOIN。
您需要为cpk子查询创建支持索引:
ALTER TABLE communityposts ADD INDEX (posttime,id,poster_id,topic_id);
此查询必须是最快的,因为cpk子查询一直只能获得五个键。
更新2011-10-10 16:28美国东部时间
此查询消除了不明确的topic_id问题:
SELECT
A.post_id, cpk.topic_id, A.post_time,
B.user_id, C.topic_title, B.username,
B.user_avatar,
FROM_UNIXTIME(post_time, '%Y-%c-%d %H:%i') as posttime
FROM
(
SELECT id,poster_id,topic_id
FROM communityposts
ORDER BY post_time DESC
LIMIT 5
) cpk
INNER JOIN communityposts A USING (id)
INNER JOIN communityusers B ON cpk.poster_id=B.user_id
INNER JOIN communitytopics C ON cpk.topic_id=C.topic_id;
答案 1 :(得分:0)
您可以减少所选字段的数量。
*运算符将选择所有(3)表中的所有字段。这可能会变得很大。那说, 我认为mysql非常聪明,可以将这个计划放在一边,这样就不需要为所选择的5行访问除了之外的数据页。
您确定所有涉及的(外国)密钥都已编入索引吗?
这是我的刺:
SELECT posts.*, FROM_UNIXTIME(post_time, '%Y-%c-%d %H:%i') as posttime
FROM communityposts posts
INNER JOIN communitytopics topics ON posts.topic_id = topics.topic_id
INNER JOIN communityusers users ON posts.poster_id = users.user_id
ORDER BY post_time DESC LIMIT 5
答案 2 :(得分:0)
然后用于排序数据的临时表可能会变得太大。我已经看到这种情况发生在/ tmp /空间不足时。 LIMIT子句不会使它更快或更容易,因为必须首先对完整数据集进行排序。
在某些情况下,MySQL不使用临时表对数据进行排序。您可以在此处阅读:http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html
如果您设法满足正确的条件(通常使用正确的索引),它也会查询您的查询。
如果这没有帮助(在某些情况下你无法摆脱繁重的排序),试着找出/ tmp /上有多少可用空间,看看它是否可以扩展。此外,如上所述,仅选择所需的列(而不是*)可以使临时表更小并且无论如何都被认为是最佳实践(因此使用显式JOIN而不是隐式JOIN)。