2016-01-01 77 views
7

我的應用程序非常密集,因此我試圖減少數據庫的負載。我使用PostgreSQL作爲rdbms,python是編程語言。 爲了減少負載,我已經在應用程序中使用了緩存機制。我使用的緩存類型是服務器緩存,瀏覽器緩存。 目前我正在調整PostgreSQL查詢緩存以使其符合在服務器上運行的查詢的特徵。在PostgreSQL中啓用查詢緩存以提高性能

問題:

  1. 是否有可能微調查詢緩存在每個數據庫級別?
  2. 是否有可能在每個表的基礎上微調查詢緩存?
  3. 請提供教程來學習PostgreSQL中的查詢緩存。
+1

如果您正在尋找Oracle提供的一些調整,答案是 - 它不在那裏。但是,這裏有幾個鏈接,您可能想閱讀http://www.postgresql.org/docs/current/static/pgprewarm.html https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server https://wiki.postgresql .ORG /維基/ Performance_Optimization – Jayadevan

回答

-1

我開發了一個緩存結果的系統,以加速從基於web的解決方案中查詢結果。我在下面重現了它的實質:

以下是通用緩存處理表和函數。

CREATE TABLE cached_results_headers (
    cache_id serial NOT NULL PRIMARY KEY, 
    date timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    last_access timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    relid regclass NOT NULL, 
    query text NOT NULL, 
    rows int NOT NULL DEFAULT 0 
); 
CREATE INDEX ON cached_results_headers (relid, md5(query)); 

CREATE TABLE cached_results (
    cache_id int NOT NULL, 
    row_no int NOT NULL 
); 

CREATE OR REPLACE FUNCTION f_get_cached_results_header (p_cache_table text, p_source_relation regclass, p_query text, p_max_lifetime interval, p_clear_old_data interval) RETURNS cached_results_headers AS $BODY$ 
DECLARE 
    _cache_id int; 
    _rows int; 
BEGIN 
    IF p_clear_old_data IS NOT NULL THEN 
    DELETE FROM cached_results_headers WHERE date < CURRENT_TIMESTAMP - p_clear_old_data; 
    END IF; 

    _cache_id := cache_id FROM cached_results_headers WHERE relid = p_source_relation AND md5(query) = md5(p_query) AND query = p_query AND date > CURRENT_TIMESTAMP - p_max_lifetime; 
    IF _cache_id IS NULL THEN 
    INSERT INTO cached_results_headers (relid, query) VALUES (p_source_relation, p_query) RETURNING cache_id INTO _cache_id; 
    EXECUTE $$ INSERT INTO $$||p_cache_table||$$ SELECT $1, row_number() OVER(), r.r FROM ($$||p_query||$$) r $$ USING _cache_id; 
    GET DIAGNOSTICS _rows = ROW_COUNT; 
    UPDATE cached_results_headers SET rows = _rows WHERE cache_id = _cache_id; 
    ELSE 
    UPDATE cached_results_headers SET last_access = CURRENT_TIMESTAMP; 
    END IF; 
    RETURN (SELECT h FROM cached_results_headers h WHERE cache_id = _cache_id); 
END; 
$BODY$ LANGUAGE PLPGSQL SECURITY DEFINER; 

以下是如何使用表和函數以上,對於名爲my_view與現場key要的範圍的整數值的範圍內選擇的給定視圖的示例。您可以將所有以下內容替換爲您的特定需求,並用表格,視圖或函數替換my_view。還根據需要更換過濾參數。

CREATE VIEW my_view AS SELECT ...; -- create a query with your data, with one of the integer columns in the result as "key" to filter by 

CREATE TABLE cached_results_my_view (
    row my_view NOT NULL, 
    PRIMARY KEY (cache_id, row_no), 
    FOREIGN KEY (cache_id) REFERENCES cached_results_headers ON DELETE CASCADE 
) INHERITS (cached_results); 

CREATE OR REPLACE FUNCTION f_get_my_view_cached_rows (p_filter1 int, p_filter2 int, p_row_from int, p_row_to int) RETURNS SETOF my_view AS $BODY$ 
DECLARE 
    _cache_id int; 
BEGIN 
    _cache_id := cache_id 
    FROM f_get_cached_results_header('cached_results_my_view', 'my_view'::regclass, 
            'SELECT r FROM my_view r WHERE key BETWEEN '||p_filter1::text||' AND '||p_filter2::text||' ORDER BY key', 
            '15 minutes'::interval, '1 day'::interval); -- cache for 15 minutes max since creation time; delete all cached data older than 1 day old 

    RETURN QUERY 
    SELECT (row).* 
    FROM cached_results_my_view 
    WHERE cache_id = _cache_id AND row_no BETWEEN p_row_from AND p_row_to 
    ORDER BY row_no; 
END; 
$BODY$ LANGUAGE PLPGSQL; 

示例:從由key BETWEEN 30044 AND 10610679過濾緩存my_view結果從1檢索行2000。首次運行,查詢結果將緩存到表cached_results_my_view中,並返回前2000條記錄。不久後再運行它,結果將直接從表cached_results_my_view中檢索,而不執行查詢。

SELECT * FROM f_get_my_view_cached_rows(30044, 10610679, 1, 2000);