2011-10-05 72 views
2

我的網站突然開始吐出以下錯誤:更有效的寫入MySQL查詢的方式?

"Incorrect key file for table '/tmp/#sql_645a_1.MYI'; try to repair it"

我將其刪除,該網站工作正常。

我的服務器技術支持人建議我清理查詢並使其更高效。

這裏的查詢:

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

運行myisamcheck,它可能會被損壞,或者你正在運行過程中出現一個相當老版本的mysql – Jauzsika

+3

使用'JOIN's而不是與'WHERE'語句交叉連接。 – mellamokb

+0

關鍵的posttime(第1行)與post_time(第5行)應該是相同的關鍵嗎? –

回答

0
  • 你可以減少選定字段的數量。

    The * operator will select all fields from all (3) tables. This may get big. That said, I think mysql is smart enough to lay this plan out so that it doesn't need to access the data pages except for the 5 rows being selected.

  • 您確定所有涉及的(外鍵)索引?

這裏是我的刺:

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 
+0

謝謝sehe,現在就給這個去吧!會回報。 –

+0

不得不編輯第4行..應該是posts.poster_id =用戶。**用戶** _編號 –

+0

可悲的是它不工作 - 我我不再得到原始錯誤,但是我也不再從我的活動飼料中獲得任何實際結果:http://www.trancetribe.com(側欄) –

0

然後用於排序的數據可能變得太大臨時表。當/ tmp /用盡空間時,我看到了這種情況。 LIMIT子句並沒有使它更快或更容易,因爲必須先完成整個數據集的排序。

在某些情況下,MySQL不使用臨時表對數據進行排序。你可以在這裏閱讀:http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

如果你設法符合正確的條件(大部分使用正確的索引),它也會把你的查詢搞糟了。

如果這沒有幫助(在某些情況下,您不能逃避重排序),請嘗試找出/ tmp /上有多少可用空間,並查看它是否可以擴展。另外,如上所述,只選擇需要的列(而不是*)可以使臨時表變小,並且無論如何都被認爲是最佳實踐(因此使用顯式連接而不是隱式連接)。

+0

我會嘗試下面的查詢,如果失敗了,我會嘗試只用我需要的列而不是SELECT *。 –

+0

Galz,好的我修好了。我只是選擇了我需要的列,現在查詢再次運行。 –

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 subquqery支撐指數:

ALTER TABLE communityposts ADD INDEX (posttime,id,poster_id,topic_id); 

該查詢必須以最快的速度因爲CPK子查詢只得到五個鍵的所有時間。

UPDATE 2011-10-10 16:28 EDT

該查詢eliminiates曖昧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; 
+0

謝謝羅蘭多。我注意到這個id需要更改爲post_id。我試過這個查詢,但是我得到了:_Column'topic_id'from from子句是ambiguous_ –

+0

我用一個查詢來更新我的答案,該查詢應該消除模糊的topic_id問題 – RolandoMySQLDBA