問題描述

這個問題讓我想起 Transient RSS feeds in wp_options not removed automatically?

瞬變應該過期並被刪除。但是,我看到處理的唯一方法是暫時過期並被請求,然後在請求期間被刪除。

如果瞬時過期但從未請求過嗎?從食品法典的描述我認為某種垃圾收集是隱含的。現在我不太確定,找不到任何執行這樣的程式碼。

那麼它會永遠被卡在資料庫中嗎?

最佳解決方案

他們現在是

從 WordPress 開始 3.7 過期的瞬變在資料庫升級時被刪除,參見 #20316


老回答

如果有人不能顯示我,否則似乎暫時不是垃圾回收。更糟糕的是,與選項不同,它們不能保證儲存在資料庫中。因此,沒有可靠的方法來獲取所有瞬變的列表,以檢查它們的到期。

一些臨時程式碼做垃圾收集如果資料庫用於儲存:

add_action( 'wp_scheduled_delete', 'delete_expired_db_transients' );

function delete_expired_db_transients() {

    global $wpdb, $_wp_using_ext_object_cache;

    if( $_wp_using_ext_object_cache )
        return;

    $time = isset ( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time() ;
    $expired = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout%' AND option_value < {$time};" );

    foreach( $expired as $transient ) {

        $key = str_replace('_transient_timeout_', '', $transient);
        delete_transient($key);
    }
}

次佳解決方案

透過 re-wording 和 re-formatting 將一些評論從討論中移到答案中。

基本上,它歸結到的是,除非你有一個超級極端的情況,他們真的不需要是”garbage collected” 。如果你從來沒有拿過他們,那麼無論他們在哪裡,都沒關係。

參見,預設情況下,瞬態儲存在選項表中。在基礎安裝中,選項表中可能有 100 個條目。每個臨時增加兩個條目,但是即使有數千個條目,它們也不會影響網站速度,因為它們不被自動載入。

在啟動時,WordPress 將選項載入到記憶體中,但它只載入其自動載入標誌已開啟的選項。瞬態不能得到這個,所以不要載入到記憶體中。只有以後實際使用的瞬變才會產生成本。

從資料庫的角度來看,options 表具有選項 ID 和選項名稱的索引。瞬態總是基於名稱 (鍵) 載入,因此它們的查詢始終是單個唯一鍵值上的簡單選擇。因此,查詢是 O(log(n)),並且超快。使用日誌 (n) 的 Big-O,您必須進入數百萬和數百萬行才能變得顯而易見。坦率地說,查詢的設定和拆卸的開銷以及實際的資料傳輸更長。查詢本身透過比較基本上執行在 zero-time 中。所以只需要額外使用的行就不會影響任何東西,只能使用額外的磁碟空間。

資料庫中的索引是 deep-read 的一種想法,對於不瞭解幕後情況的人來說,這些想法是沒有意義的。資料庫設計用於快速資料檢索,從頭開始,可以處理這種事情沒有問題。這是一個很好的閱讀:http://en.wikipedia.org/wiki/Index_(database)

現在,以最明顯的方式 (呼叫 SQL DELETE) 清理它們並不會從資料庫中刪除它們。它只是從索引中刪除它們,並將該行標記為”deleted” 。再次,這只是資料庫的工作原理。要實際清除磁碟空間,您必須繼續,然後執行一個 OPTIMIZE TABLE,這不是一個快速的操作。這需要時間。可能更多的時間比它的價值。總共可以節省 CPU 時間,這可能還不夠。

如果您有某種情況導致連續插入未被使用的新瞬變,則需要找到基礎問題。什麼是插入這些瞬變?他們在使用更改或變更的金鑰嗎?如果是這樣,那麼導致這個的外掛或程式碼應該是固定的,基本上不這樣做。這將會更有幫助,因為沒有正確建立它們的程式碼可能不是檢索它們,因此做的更多的工作。

另一方面,可能存在像每個帖子這樣的事物建立瞬變的情況。這可能是完全可以接受的。我自己在證監會做這個,以儲存來自 Facebook 的意見。每個帖子都有一個潛在的瞬態關聯,這意味著每個帖子有兩個額外的行。如果你有 10k 的帖子,那麼在選項表中最終會有 20k 行。這不錯還是緩慢,因為資料庫真的很在乎,100 行和 20,000 行之間的差別很小。這都是索引。它的速度很快。 Sub-sub-milliseconds 。

當你開始上百萬行時,我會擔心。當選項表的大小增加到數百兆位元組以上時,我會很關心,仔細看看。但一般而言,除極端情況外,這不是一個問題。任何比像大型新聞網站那樣小的東西,數以萬計的帖子,這當然不是問題。而對於任何足夠大的網站來說,這是一個問題,您應該使用某種外部物件快取,而在這種情況下,瞬態會自動儲存在資料庫中而不是資料庫中。

第三種解決方案

奧託 – 我不能不同意你的意見。問題是,最終所有這些瞬間,桌子的大小變得可笑。它不會使數百萬行陷入死鎖。我正在處理一個超過 130k 行的選項表,並定期掛起。因為值欄位是一個大的文字型別,甚至只尋找”autoload” 行成為一個噩夢的表現。這些值欄位與行資料的其餘部分分開儲存。即使它在邏輯上是同一個表的一部分,連線必須發生,以便拉出你想要的行。加入現在永遠是因為您需要的資料遍佈磁碟上的所有位置。 Profiling(使用 jet profiler for mysql) 證明瞭這一點。

將 auto-load 新增到群集金鑰可能有助於解決此問題。自動載入描述中的叢集 (例如 ID ASC) 將允許所有自動載入行首先在磁碟上聚集在一起。即使我仍然認為你從資料庫的角度來看待一個巨大的壓力。

就個人而言,我認為這個系統的設計是一個很好的選擇。選項表似乎已經變成了一般的 catch-all 很多東西。如果值欄位足夠小以便與 rowdata 的其餘部分包含在同一頁面上,那麼就可以了,並且可以有效地建立索引。不幸的是,情況並非如此。誰設計這個需要回到 DB101 課堂。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。