2015-06-03 3 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" 
     ; 
Смежные вопросы