2015-06-03 60 views
0

我正在使用Postgres 9.3並想知道是否有一種方法來加速大型表上的特定查詢。這些都是我的表:Postgres:加速位圖堆掃描?

         Table "public.frontend_prescription" 
     Column  |   Type   |        Modifiers 
-------------------+-------------------------+-------------------------------------------------------------------- 
id    | integer     | not null default nextval('frontend_prescription_id_seq'::regclass) 
presentation_code | character varying(15) | not null 
actual_cost  | double precision  | not null 
processing_date | date     | not null 
pct_id   | character varying(3) | not null 
Indexes: 
    "frontend_prescription_pkey" PRIMARY KEY, btree (id) 
    "frontend_prescription_4e2e609b" btree (pct_id) 
    "frontend_prescription_528f368c" btree (processing_date) 
    "frontend_prescription_b9b2c7ab" btree (presentation_code) 
    "frontend_prescription_cost_by_pres_code" btree (presentation_code, pct_id, actual_cost) 
    "frontend_prescription_presentation_code_69403ee04fda6522_like" btree (presentation_code varchar_pattern_ops) 
    "frontend_prescription_presentation_code_varchar_pattern_ops_idx" btree (presentation_code varchar_pattern_ops) 

      Table "public.frontend_pct" 
     Column  |   Type   | Modifiers 
-------------------+-------------------------+----------- 
code    | character varying(3) | not null 
name    | character varying(200) | 
org_type   | character varying(9) | not null 

這是我的查詢所有CCG組織通過每月能拿到消費,在一個特定的presentation_code

SELECT sum(frontend_prescription.actual_cost) as val, 
     frontend_prescription.pct_id as row_id, 
     frontend_prescription.processing_date as date, 
     frontend_pct.name as row_name 
FROM frontend_prescription, frontend_pct 
WHERE (presentation_code='0407041T0BBACAC') 
AND frontend_prescription.pct_id=frontend_pct.code 
AND frontend_pct.org_type='CCG' 
GROUP BY frontend_prescription.pct_id, frontend_pct.code, date 
ORDER BY date, row_id 

下面是關於這個查詢的EXPLAIN (ANALYSE, BUFFERS)的結果: http://explain.depesz.com/s/YrR5

它看起來像緩慢的部分是frontend_prescription上的位圖堆掃描。有什麼辦法可以讓這個更快嗎?特別是,我注意到它循環了211次(數據中發現的每個pct一次)。

該表有數百萬行,所以我懷疑沒有,但只是想檢查是否有什麼明顯的我可以做。

+0

'frontend_pct.code'應該是frontend_pct的主鍵? (順便說一句:爲什麼是字符?) – wildplasser

+0

它是字符,因爲這些編碼是字符編碼,比如'03Q'。是的,這是主鍵,對不起,我省略了索引:''frontend_pct_pkey「PRIMARY KEY,btree(code)'。 – Richard

回答

0
-- the tables (Indexes omitted) 
CREATE Table frontend_pct (
     code varchar(3) not null PRIMARY KEY 
     , name varchar(200) 
     , org_type  varchar(9) not null 
     ); 

CREATE TABLE frontend_prescription (
id  SERIAL NOT NULL PRIMARY KEY 
, presentation_code varchar(15)  not null 
, actual_cost double precision not null 
, processing_date  date not null 
, pct_id  varchar(3) not null REFERENCES frontend_pct(code) 

     ); 

-- the rewritten query (shows some flaws) 
EXPLAIN ANALYZE 
SELECT 
     pr.pct_id as row_id 
     , pr.processing_date as zdate -- <<-- renamed this; "date" is a typename 
     , pc.name as row_name 
     , sum(pr.actual_cost) as val 
FROM frontend_prescription pr 
JOIN frontend_pct pc ON pr.pct_id=pc.code AND pc.org_type='CCG' 
WHERE pr.presentation_code='0407041T0BBACAC' 
GROUP BY pr.pct_id, pc.code, zdate 
     -- ^^ ------ ^^ <- these are the same (maybe you meant pc.name ??) 
         -- (which is functionally dependent on pc.code) 
ORDER BY zdate, row_id -- <-- strange order; why not the same as "GROUP BY" 
     ;