2013-08-20 68 views
1

在我的應用程序中,我嘗試儘可能少地查詢所需的全部數據。這通常會導致帶有許多聯接的大型查詢。這限制了您可以使用像Memcache或Redis這樣的軟件進行緩存(據我所知)。對於大量查詢,您不知道哪些部分可能已被緩存。您似乎必須在較小的部分查詢所有內容,以便這些小部分可以單獨緩存。這個想法是,你只需要做幾十個小的查詢就可以填充緩存,而且大多數情況下你會打緩存而不是查詢。這是多高的PHP/MySQL網站處理這個?即使您有很多連接的大型查詢,是否有一種有效緩存的好方法?正在查詢MySQL數據庫幾十次,以便有效緩存比緩存少的大型查詢更好?

例子:

SELECT user.name, user.birthday 
FROM follower 
    INNER JOIN user ON (user.id = follower.user) 
WHERE follower.following = '1' 

此查詢的結果包括可以被緩存的名字和下面的用戶1.此查詢的結果的任何用戶的生日,但得到的用戶追隨者時纔有用1.

替代:

SELECT follower.user 
FROM follower 
WHERE follower.following = '1' 

對於每個結果?上述查詢通過follower.user填充:

SELECT name, birthday FROM user where user.id = ? 

在這種情況下,我們可以檢查,看看用戶的名字和生日都從MySQL查詢之前緩存?如果它們沒有被緩存,或者有些被緩存,有些則不被緩存,然後抓取丟失的並緩存它們。您還可以緩存跟隨者ID列表,然後下次不需要運行任何查詢。不同之處在於,用戶的姓名和生日對其他任何用戶來說都是有用的,這些用戶在任何其他情況下都需要關於這些關注者的信息。

我錯過了與更大的查詢緩存的東西?或者第二種方式是正確的?

+0

「這通常會導致大量查詢與許多聯接」,也意味着很多結果行? –

+0

我相信用PHP有一些prepare_query函數可以在查詢上做一些工作,然後你所要做的就是設置參數來運行它。這些準備好的語句可以更快地執行大量查詢,因爲數據庫引擎無需在它們之前做所有準備工作。 –

回答

2

正確的答案是:這取決於。

緩存是一種優化識別使用模式的方法,通過重複使用上次運行的數據來生成重複的昂貴數據。

所以你應該回答的第一個問題是:在那裏有一個觀察到的重複使用模式,有一個明顯的「昂貴」的數據生成步驟?如果沒有:不要使用你仍然不需要的緩存,等到你可以觀察一些東西。

您應該能夠回答的第二個問題是:您可以測量使用和不使用緩存需要多長時間,並且差異是否明顯?

而第三個要回答的重要問題是:如果原始數據發生變化,並且您希望立即顯示新數據,如何從過時的信息中清除緩存?

因此,在你的情況下,你問的是,如果使用緩存來獲取大量小的,但看似更普遍的查詢,然後結合起來比緩存一個大的查詢更有好處。沒有理論上的答案,因爲它取決於高速緩存命中的結果與組合結果的多個高速緩存命中的比較。向緩存發出多個請求可能比從原始源獲取數據要慢,並且將數據組合成所需的複雜結果也可能比直接從緩存中獲取一個複雜結果要慢。另外,如果對於組合結果使用多個緩存條目,則現在必須處理大量情況,其中只有部分信息已過期,而其他情況則不是。所以結果變得更加不可靠 - 你不能確定結果的每一部分是否是最新的,或者是多大的。

0

@Sven你明白了!我增加幾個原始的建議。

@Barakat對於MySql來說,大型查詢通常並不是什麼大問題,設計良好的db,索引和調整引擎參數通常會帶來很高的性能。

很多小的查詢會導致很多開銷(緩存或不緩存),我通常會避免這種情況。

如果你的大查詢給出了很大的結果(成千上萬行),可能是你可以避免它分頁結果或限制答案獲得最佳分數。

一個非常簡單和影響的工具來調整你的MySQL服務器MysqlTuner.pl,因爲你可以使用MySQL 內部緩存,而不擔心相干!