問題描述

我正在閱讀一些 best practices from 10up,他們提到在 WP_Query 中將這兩個標誌設定為 false(取決於您正在查詢的內容):

  • 'update_post_meta_cache' => false:當後期後設資料不被使用時很有用。

  • 'update_post_term_cache' => false:當分類術語不被使用時很有用。

我假設它使用像 update_post_caches()這樣的東西,但我甚至不敢肯定這是什麼意思。有人可以解釋這兩個標誌在 WP_Query 中的含義,它們是多麼有用嗎?更多的資訊越好,因為我不太瞭解 WordPress 如何快取的東西,但是對於這兩個標誌的一個深思熟慮的答案也是可以接受的。

最佳解決方案

物件快取無處不在

WordPress 儘可能地減少資料庫查詢的數量。

例如,任何時候您獲得元欄位或分類欄位,在查詢資料庫之前,WordPress 會檢視是否已經查詢並儲存在快取中,並從中返回,而不是查詢資料庫。

“cache job” 是透過 WP_Object_Cache 類和 wp_cache_*函式完成的 (這是包裝類的方法。)

快取生活的地方

預設情況下,”cache” 只不過是一個 PHP 全域性變數。這意味著它在記憶體中,也意味著它會在每個請求上消失。

但是,透過 dropins(advanced-cache.php 和/或 object-cache.php),可以設定一個自定義的方式來處理這個快取。

通常,這個下拉選單用於設定”survive” 單個請求的某種快取機制。

由於這個原因,在 WP 的人中,這些都被稱為”persistent cache” 外掛 (即使在泡沫之外,”cache” 和”persistent” 也不會一起做出很大的意義) 。

現在的熱門選擇是 MemcachedRedis

因此,使用”persistent cache” 外掛可以大大減少資料庫查詢的數量,因為快取在每個請求上都不會更新。

一些例子

$foo = get_post_meta('foo', $post_id, true);
// a lot of code in the middle
$bar = get_post_meta('bar', $post_id, true);

上述 2 行程式碼將最多觸發 1 個資料庫查詢。

實際上,當您查詢自定義欄位時,該資料庫的所有欄位都將從資料庫中檢索,透過物件快取進行快取,後續請求從快取中提取資料,而不是從資料庫中提取資料。

分類術語也是一樣,WordPress 會將分類的所有術語拉一次,然後從快取中返回。

物件快取在 WordPress 中被廣泛使用。不僅用於帖子,元值和分類,還可以為使用者,評論,主題資料…

什麼 WP_Query 與所有這一切有關係?

當您透過 WP_Query 查詢某些帖子時,預設情況下,WordPress 不僅可以從資料庫 (或從快取中快取) 中提取它們,還可以更新所有自定義欄位的快取以及與拉出的帖子相關的所有分類。

所以當你打電話時,例如 get_the_terms()get_post_meta(),而迴圈的帖子透過 WP_Query 得到,你實際上並不觸發任何資料庫查詢,而是從快取中提取資訊。

好,不是嗎

是的,但它帶有成本。

快取更新”magic”,WordPress 透過 WP_Query 拉動帖子發生在 update_meta_cache for meta 和 update_object_term_cache 用於分類。

如果您檢視這些函式的原始碼,您將看到 WordPress 在每個函式中只執行一個 db 查詢,但也進行了大量的處理。例如,在 update_object_term_cache 中有 7 個巢狀的 foreach … 如果你有很多分類,每頁的帖子數量很多,這不是很好。

關於 WP_Query 引數,最後

'update_post_meta_cache''update_post_term_cache'在設定為 false 時會做的是分別防止 WordPress 更新快取的自定義欄位和分類。

在這種情況下,第一次查詢自定義欄位或分類法時,將觸發資料庫查詢,並快取資料。

值得嗎?

像往常一樣,答案是否決定。大多數時間將這些值設定為 false 是一個不錯的選擇,因為它不需要時會阻止不必要的處理和資料庫查詢,並且無論如何,首次需要自定義欄位/分類術語,快取都會更新。

但是,如果您打算在 C 迴圈中呼叫 get_post_meta(),並且您將為帖子支援的所有 (或大多數) 分類而呼叫 get_the_terms(),那麼快取更新將被觸發,並且可能沒有實際的有利於將這些查詢引數設定為 false

次佳解決方案

主要的興趣點是 update_post_caches 功能。 WP_Query 從 DB 獲取了所有的帖子後被呼叫。通常,您首先要發帖的原因是顯示它們,通常意味著根據後設資料顯示術語和某些內容,因此,WP_Query 還將預設查詢與返回的帖子相關的後設資料和術語資料的 DB 並儲存快取*。這些資訊在 WP_Query 返回的資料中不是明確提供的,但是當您呼叫相關 API 以獲取特定帖子的術語和元資訊時,它將已經在記憶體中可用,並且不需要傳送新的查詢到 DB 。

這使 Wordpress 能夠透過僅傳送一個請求來獲取所有帖子的資訊而不是向每個帖子傳送請求來減少與向 DB 傳送請求相關的開銷。

現在我找不到什麼時候不希望快取更新的任何非常簡單的例子,但是如果你只想要所有帖子的標題列表,可能是一個瑣碎的例子。因此,您不需要術語或後設資料。

* cache – 這裡最重要的是基於記憶體的快取,即使沒有任何物件快取外掛的活動,WP 也可以儲存其中的所有資料。顯然,當您有物件快取時,資訊也將儲存在那裡。

參考文獻

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