2011-10-10 59 views
2

我運行的站點有大量搜索得到執行。這些搜索並不重要,並且需要將多個數據片段加入到結果中。優化對information_schema的查詢

我的解決辦法是存儲在兩個表的搜索結果:搜索和SearchResult所

搜索包含搜索的元數據

SearchResult所包含兩列idsearch,IDDATA是一個內存表

在爲了防止搜索結果的內存溢出,我們定期修剪這個表並刷新陳舊的數據。據我所知,內存表具有表級別鎖定,因此在修剪過程中,searchresults表會被阻止並導致網站性能下降。

解決方案是爲每個搜索創建一個新表,然後在搜索失效時放棄此searchresults_xxxx表。

我這樣做是通過首先刪除搜索表中陳舊的條目。然後執行以下操作:

select table_name 
from information_schema.tables 
where 
    table_schema = 'mysite_datawarehouse' 
    and table_name not in (select concat('searchresults_', idsearch) from searches); 

經常有幾千場比賽的襲擊,導致平均查詢時間約30秒左右。在此期間,表現再次下降,我又回到了原點。有沒有更好的方法來寫這個?或者更好的方法來設計這個?

謝謝!

+0

你能定期定義嗎?如果你的意思是每天凌晨2點是否重要,需要30秒?如果你在白天做這件事,你只能在晚上做嗎?爲了改善你的查詢,你可以把它變成一個連接。如果你的桌子有任何大小的話,「不在」可能是令人討厭的。 – Ben

+0

每10分鐘搜索一次無效。在清理之前,搜索通常有5k行。每個搜索通常具有存儲在搜索結果中的〜1k和〜20k之間的結果。所以清除舊的結果變得相當重要。 – bmancini

回答

0

我剛剛問過並解決了一個相關的Q:Slow query on information_schema.tables。您在這裏遇到的問題是查詢將通過爲* .FRM文件執行目錄掃描來枚舉數據目錄中的所有表。它也可能打開每個FRM文件並讀取其標題。這會很慢。

我的Q是爲什麼查詢信息模式呢?我假設你相信搜索的內容。爲什麼不僅在搜索中包含創建時間戳字段並選擇創建時間戳超過特定時間的所有表名稱。如果它直接做一個循環做一個drop table(如果存在的話),甚至將這個清理過程移動到存儲過程中。對信息模式執行主要查詢並不會增加任何內容,並且會降低修剪過程的速度。

0

這裏是你原來的查詢

select table_name 
from information_schema.tables 
where 
    table_schema = 'mysite_datawarehouse' 
    and table_name not in 
    (select concat('searchresults_', idsearch) from searches); 

我會很容易想到,如果有一堆InnoDB表的導航通過

嘗試重構查詢查詢進行LEFT JOIN如下它是緩慢的:

select A.table_name 
from (select concat('searchresults_', idsearch) table_name from searches) A 
LEFT JOIN 
(select table_name FROM information_schema.tables 
where table_schema = 'mysite_datawarehouse') B 
USING (table_name) 
WHERE B.table_name IS NULL;