2010-12-09 205 views
0

以下問題讓我頭疼。MySQL查詢緩存,複雜SQL查詢

我已經建立了我的MySQL服務器來使用「查詢Chaching」。

set global query_cache_size = 10000000; 

看來我的查詢緩存發揮作用是因爲

SHOW STATUS LIKE 'Qcache%'; 

輸出如下

+-------------------------+----------+  
| Variable_name  | Value |   
+-------------------------+----------+  
| Qcache_free_blocks  | 1  | 
| Qcache_free_memory  | 47223976 | 
| Qcache_hits    | 6709  |          
| Qcache_inserts   | 2314  |          
| Qcache_lowmem_prunes | 0  |         
| Qcache_not_cached  | 365  |         
| Qcache_queries_in_cache | 441  |         
| Qcache_total_blocks  | 960  |          
+-------------------------+----------+ 

但是,nevertheles以下(複雜的查詢,有內選擇等)不會被緩存。

它還有至少0.8秒檢索此查詢的數據。我怎樣才能把mysql的這個查詢的結果存放在它的緩存中

我試圖刪除內部的選擇,但這並沒有區別。

SELECT p.id 
    AS 
    project_id, 
    p.code 
    AS project_code, 
    p.title 
    AS project_title, 
    p.start_date 
    AS project_start_date, 
    p.end_date 
    AS project_end_date, 
    p.modf 
    AS project_modf, 
    (p.budget * (SELECT 1/r.VALUE 
       FROM exchange_rates r 
       WHERE r.class_currency_id = p.class_budget_currency_id)) 
    AS 
    project_budget, 
    (SELECT z.txt 
    FROM sys_labels z 
    WHERE z.id = ps.value_label_id 
      AND z.lng = 'en') 
    AS project_status, 
    (SELECT z.txt 
    FROM sys_labels z 
    WHERE z.id = ps.data_label_id 
      AND z.lng = 'en') 
    AS project_color, 
    GROUP_CONCAT(DISTINCT pt.class_topic_id) 
    AS projects_thematic_area_ids, 
    u.id 
    AS project_owner_id 
FROM projects AS p 
    LEFT JOIN projects_thematic_areas AS pt 
    ON pt.project_id = p.id 
    LEFT JOIN sys_users AS u 
    ON u.id = p.owner_uid 
    LEFT JOIN class_data s 
    ON s.id = p.class_status_id 
    LEFT JOIN class_data AS ps 
    ON ps.id = s.id 
    LEFT JOIN sys_labels AS prdz1 
    ON prdz1.id = prd.value_label_id 
     AND prdz1.lng = 'en' 
    LEFT JOIN sys_labels AS prdz2 
    ON prdz2.id = prd.data_label_id 
     AND prdz2.lng = 'en' 
    LEFT JOIN projects_locations AS pl 
    ON pl.project_id = p.id 
    LEFT JOIN class_data AS l 
    ON l.id = pl.class_location_id 
    LEFT JOIN class_data AS r 
    ON r._lft <= l._lft 
     AND r._rgt >= l._rgt 
     AND r._level = 1 
     AND r.class_id = 5 
    LEFT JOIN class_data AS c 
    ON c._lft <= l._lft 
     AND c._rgt >= l._rgt 
     AND c._level = 2 
     AND c.class_id = 10 
    LEFT JOIN projects_donors AS pd 
    ON pd.project_id = p.id 
    LEFT JOIN institutions AS i 
    ON pd.inst_id = i.id 
    LEFT JOIN class_data AS ic 
    ON ic.id = i.class_country_id 
    LEFT JOIN projects_deliverables AS d 
    ON d.project_id = p.id 
WHERE 1 = 1 
    AND p.is_del = "f" 
    AND p.is_active = "t" 
GROUP BY p.id 
ORDER BY p.modf DESC, 
     p.code DESC 

任何幫助apprechiated ....

問候

J.

回答

1

除了以前的答案:查詢緩存將不被使用即使查詢在任何選定的表中有變化時也在那裏。

但是,當你沒有從中選擇任何東西時,你爲什麼要加入這些表格?如果你可以加入它,你也許不應該再選擇任何東西。

像這樣的選擇完全一樣:

SELECT 
    p.id AS project_id, 
    p.code AS project_code, 
    p.title AS project_title, 
    p.start_date AS project_start_date, 
    p.end_date AS project_end_date, 
    p.modf AS project_modf, 
    p.budget * (1/r.VALUE) AS project_budget, 
    z1.txt AS project_status, 
    z2.txt AS project_color, 
    GROUP_CONCAT(DISTINCT pt.class_topic_id) AS projects_thematic_area_ids, 
    u.id AS project_owner_id 
FROM 
    projects AS p 
    LEFT JOIN projects_thematic_areas AS pt ON pt.project_id = p.id 
    LEFT JOIN sys_users AS u ON u.id = p.owner_uid 
    LEFT JOIN exchange_rates AS r ON r.class_currency_id = p.class_budget_currency_id 
    LEFT JOIN class_data s ON s.id = p.class_status_id 
    LEFT JOIN class_data AS ps ON ps.id = s.id 
    LEFT JOIN sys_labels AS z1 ON z1.id = ps.value_label_id AND z1.lng = 'en' 
    LEFT JOIN sys_labels AS z2 ON z2.id = ps.data_label_id AND z2.lng = 'en' 
WHERE 
    1 
    AND p.is_del = "f" 
    AND p.is_active = "t" 
GROUP BY 
    p.id 
ORDER BY 
    p.modf DESC, 
    p.code DESC 

當然,你對所有的外鍵(組合)的索引,其中字段和組字段。考慮爲你的布爾值使用tinyint或enum字段。您可能還需要考慮不選擇該GROUP_CONCAT,以免丟失GROUP BY。如果您確定關係存在,也許使用INNER JOIN而不是LEFT JOIN。

0

您可以嘗試SELECT SQL_CACHE ... FROM ...

0

一些基本的東西,你可以嘗試:

  • 閱讀Query Cache Documentation,以確保您瞭解的基礎知識,並具有安裝它正確。
  • 理想情況下隔離你的MySQL數據庫服務器,以便它只運行你給它的命令。如果你不能這樣做,那麼嘗試在另一臺機器上設置並運行測試。
  • 運行一個簡單的查詢並查看Qcache_hitsCom_select狀態變量,以確定查詢緩存是否被命中。
  • 嘗試複雜的查詢並監視相同的值。如果你的查詢沒有觸及緩存,那麼嘗試更小的部分,直到找出導致它不被緩存的原因。如果它正在被緩存,那麼問題可能是由於查詢中的任何表在查詢之間更新,這將使緩存副本無效。