你實際上有兩個問題需要進一步解決。
其中一個你尚未遇到但你可能比你想要更早的地方是要在你的統計表中插入吞吐量。
另一個,你在你的問題中概述,實際上是使用統計。
讓我們從輸入吞吐量開始。首先,如果你這樣做,不要跟蹤可能使用緩存的頁面上的統計信息。使用一個將腳本廣告爲空的JavaScript腳本或者一個像素的圖像,並在您正在跟蹤的頁面中包含後者。這樣做可以輕鬆緩存您網站的剩餘內容。
在電信業務中,不是通過電話撥打與計費相關的實際插入內容,而是將其放入內存並定期與磁盤同步。這樣做可以管理巨大的吞吐量,同時保持硬盤驅動器的快樂。
要在您的結尾進行類似操作,您需要一個原子操作和一些內存中的存儲。以下是一些基於memcache的僞代碼,用於執行第一部分...
對於每個頁面,您需要一個Memcache變量。在Memcache中,increment()是原子的,但add(),set()等不是。所以,你需要警惕不要錯過計數命中時併發進程,同時加在同一個頁面:
$ns = $memcache->get('stats-namespace');
while (!$memcache->increment("stats-$ns-$page_id")) {
$memcache->add("stats-$ns-$page_id", 0, 1800); // garbage collect in 30 minutes
$db->upsert('needs_stats_refresh', array($ns, $page_id)); // engine = memory
}
定期,例如每5分鐘(相應地配置超時),你要同步所有這一切都交給了數據庫,沒有任何影響彼此或現有命中計數的併發進程的可能性。對於這一點,你做任何事情(這使您對現有數據的所有意圖和目的鎖定)之前遞增的命名空間,睡了一點,所以,如果需要引用現有的命名空間現有的流程完成了:
$ns = $memcache->get('stats-namespace');
$memcache->increment('stats-namespace');
sleep(60); // allow concurrent page loads to finish
完成後,您可以安全地遍歷頁面標識,相應地更新統計信息,並清理needs_stats_refresh表。後者只需要兩個字段:page_id int pkey,ns_id int)。還有一點比簡單的選擇,插入,更新和刪除語句從你的腳本運行,但是,繼續...
正如另一個回覆者建議,爲您的目的維護中間狀態是相當合適的:存儲批次的命中而不是個人命中。在最多情況下,我假設您需要每小時的統計數據或每小時一次的統計數據,因此處理每15分鐘批量加載的小計就可以了。
更重要的是,爲了您的利益,由於您使用這些總計來訂購帖子,因此您希望存儲總計總計並對後者進行索引。 (我們會到更遠的地方。)
保持總計的一種方法是添加一個觸發器,在插入或更新到統計表時,將根據需要調整統計總數。
這樣做時,要特別警惕死鎖。儘管沒有兩個$ns
運行會混合它們各自的統計數據,但是兩個或更多進程同時觸發上述「增量$ ns」步驟仍然存在(儘管很小)的可能性,並且隨後發出尋求同時更新計數的語句。獲得advisory lock是避免與此相關的問題的最簡單,最安全,最快速的方法。
假設您使用諮詢鎖,在update語句中使用total = total + subtotal是完全可以的。
雖然關於鎖的話題,請注意更新總數將需要對每個受影響的行進行排它鎖定。既然你是按他們的順序排列的,你不希望他們一次處理完所有東西,因爲這可能意味着需要長時間保持排他鎖。這裏最簡單的方法是將插入的數據以較小的批次處理(例如1000),然後每次都進行提交。
對於中介統計信息(每月,每週),向您的統計信息表中添加一些布爾字段(MySQL中的bit或tinyint)。讓每個人都存儲它們是否包括每月,每週,每日統計數據等。在他們身上放置一個觸發器,以增加或減少stat_totals表中的適用總數。
作爲結束語,請提供一些想要存儲實際計數的位置。它需要是一個索引字段,而後者將被大量更新。通常,您需要將它存儲在自己的表格中,而不是存儲在網頁表格中,以避免使用(更大)死行來混亂網頁表格。
假設你做你的最終查詢上述所有變爲:
select p.*
from pages p join stat_totals s using (page_id)
order by s.weekly_total desc limit 10
它應該是足夠快與weekly_total索引。最後,我們不要忘記最明顯的一點:如果你反覆運行這些相同的總/每月/每週/每次查詢,它們的結果也應該放在memcache中。
如果您發佈表結構以查看需要添加索引的位置,甚至解釋緩慢查詢,這將非常有用。 – 2011-06-02 08:35:13
或查詢本身 – Belinda 2011-06-02 08:36:33
我已經添加了表格方案和慢SQL查詢。 – Owen 2011-06-02 09:15:49