2008-12-06 73 views
1

嗯,我有一個視頻網站和幾個表,分別是:MySQL查詢需要15秒以上運行;我能做些什麼來緩存/改進它?

標籤

id ~ int(11), auto-increment [PRIMARY KEY] 
tag_name ~ varchar(255) 

videotags

tag_id ~ int(11) [PRIMARY KEY] 
video_id ~ int(11) [PRIMARY KEY] 

視頻

id ~ int(11), auto-increment [PRIMARY KEY] 
video_name ~ varchar(255) 

現在,此時標籤表具有> 1000行,而videotags表具有> 32000行。所以當我運行一個查詢來顯示從最常見到最不常見的所有標籤時,它需要15秒鐘才能執行。

我使用PHP和我的代碼(淡化爲簡單起見)如下:

foreach ($database->query("SELECT tag_name,COUNT(tag_id) AS 'tag_count' FROM tags LEFT OUTER JOIN videotags ON tags.id=videotags.tag_id GROUP BY tags.id ORDER BY tag_count DESC") as $tags) 
{ 
    echo $tags["tag_name"] . ', '; 
} 

現在牢記,這是100%準確的對我來說並不重要,因爲它是快。所以即使查詢一天執行一次,其結果在一天中的其餘時間使用,我也不在乎。

我對MySQL/PHP緩存絕對一無所知,請大家幫忙!

+1

請直接或通過PHPmyAdmin在查詢上運行EXPLAIN。 http://dev.mysql.com/doc/refman/5.0/en/explain.html – 2008-12-06 21:57:02

回答

3

MarkR提到的索引。請確保您:

create index videotags_tag_id on videotags(tag_id); 
0

我認爲你最好的辦法是創建一些總結表,當事情發生變化時你會保留這些表。

上述查詢需要掃描,以便通過查找該組中的聚集體在表中的所有行 - 沒有WHERE子句。沒有where子句的查詢沒有優化的希望,因爲它必須檢查每一行。

修復的方法是創建一個彙總表使用相同的數據作爲查詢(或類似),您將不得不從時間維持時間當數據變化或顯著改變的結果。

只有你能決定,根據您的應用程序和數據的性質,無論是適當的更新計劃的基礎上彙總表,每次更新,或某種組合。

當你在做一個連接,正確的索引仍然是有益的,但你知道,正確的,已經做了呢?

0

您是使用InnoDB還是MyISAM?在MyISAM中COUNT基本上是免費的,但是在InnoDB中它必須對這些行進行物理計數。

+0

我使用的MyISAM – 2008-12-06 22:08:32

+1

計數只對MyISAM的自由,如果你正在計算所有行,而不是如果您要統計組。然後,它是如你所期望一樣昂貴(在這種情況下,需要掃描整個表,無論哪種方式) – MarkR 2008-12-07 07:32:39

+0

尼斯,感謝澄清MarkR – 2008-12-09 15:31:44

2

32,000行仍然是一個小表 - 你的表現不應該那麼糟糕。

你能在你的查詢運行EXPLAIN - 我猜你的索引是錯誤的地方。

你說的問題:

tag_id ~ int(11) [PRIMARY KEY] 
video_id ~ int(11) [PRIMARY KEY] 

的順序是他們肯定?如果不是,那麼它不會使用索引。

相關問題