2016-01-01 17 views
7

Uygulamam çok yoğun bir şekilde veritabanı yoğun olduğundan, veritabanındaki yükü azaltmaya çalışıyorum. Ben PostgreSQL rdbms kullanıyorum ve python programlama dili. Yükü azaltmak için uygulamada zaten bir önbellek mekanizması kullanıyorum. Kullandığım önbelleğe alma türü bir sunucu önbelleği, tarayıcı önbelleği. Şu anda sunucuda çalıştırılan sorguların özelliklerine uygun olarak PostgreSQL sorgu önbelleğini ayarlıyorum.Performansı iyileştirmek için postgreSQL'te sorgu önbelleğini etkinleştir

Sorular:

  1. bir veritabanı başına düzeyinde ince ayar Sorgu önbelleği mümkün mü?
  2. Sorgu önbelleğini her tablo için ince ayar yapmak mümkün mü?
  3. Lütfen PostgreSQL'de sorgu önbelleğini öğrenmek için öğretici verin.
+1

Oracle'da kullanabileceğiniz bir tür tweaks arıyorsanız, yanıt - yok. Ama burada okumak isteyebileceğiniz birkaç link var: http://www.postgresql.org/docs/current/static/pgprewarm.html https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server https: //wiki.postgresql .org/wiki/Performance_Optimization – Jayadevan

cevap

-1

Web tabanlı bir çözümden sorgulanan sonuçları hızlandırmak için sonuçları önbelleğe almak için bir sistem geliştirdim. Aşağıda özünde aşağıdaki gibi yaptım:

Aşağıdakiler, genel önbelleğe alma işlem tabloları ve işlevleridir. Aşağıdaki

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; 

tamsayı değerler aralığında olacak şekilde seçilebilir için bir alan key ile my_view adlandırılan belirli bir görünüm için, yukarıdaki tablo ve işlevleri kullanma bir örnektir. Aşağıdakileri özel gereksinimlerinizle değiştirir ve my_view'u bir tablo, bir görünüm veya işlevle değiştirirsiniz. Ayrıca filtre parametrelerini gerektiği gibi değiştirin.

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; 

Örnek: key BETWEEN 30044 AND 10610679 tarafından filtre önbelleğe my_view sonuçları ile 2000 1 satırları al. İlk kez çalıştırın ve sorgunun sonuçları tabloya cached_results_my_view önbelleğe alınacak ve ilk 2000 kayıtları iade edilecektir. Kısa bir süre sonra tekrar çalıştırın ve sonuçlar sorguyu yürütmeden doğrudan tablodan cached_results_my_view alınacaktır.

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