Ich benutze Postgres 9.4. Dies ist meine Tabelle:Postgres scheint den falschen Index zu verwenden?
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
total_items | integer | not null
processing_date | date | not null
practice_id | character varying(6) | not null
Indexes:
"frontend_prescription_pkey" PRIMARY KEY, btree (id)
"frontend_prescription_6ea07fe3" btree (practice_id)
"frontend_prescription_by_practice" btree (presentation_code, practice_id)
"frontend_prescription_by_practice_and_code" btree (practice_id, presentation_code varchar_pattern_ops)
"frontend_prescription_idx_date_and_code" btree (processing_date, presentation_code)
Dies ist meine Frage:
EXPLAIN (analyse, verbose)
SELECT SUM(total_items) AS items, SUM(total_items) AS numerator
FROM frontend_prescription
WHERE ((presentation_code LIKE '0601012Z0%') OR (presentation_code LIKE '0601012X0%') OR (presentation_code LIKE '0601012V0%'))
AND (practice_id='A81001')
AND (processing_date='2016-01-01')
Dies ist die Ausgabe:
Aggregate (cost=12.26..12.27 rows=1 width=4) (actual time=16898.277..16898.277 rows=1 loops=1)
Output: sum(total_items), sum(total_items)
-> Index Scan using frontend_prescription_idx_date_and_code on public.frontend_prescription (cost=0.57..12.26 rows=1 width=4) (actual time=9220.091..16898.251 rows=6 loops=1)
Output: id, presentation_code, presentation_name, total_items, net_cost, actual_cost, quantity, processing_date, price_per_unit, chemical_id, pct_id, practice_id, sha_id
Index Cond: (frontend_prescription.processing_date = '2016-01-01'::date)
Filter: (((frontend_prescription.practice_id)::text = 'A81001'::text) AND (((frontend_prescription.presentation_code)::text ~~ '0601012Z0%'::text) OR ((frontend_prescription.presentation_code)::text ~~ '0601012X0%'::text) OR ((frontend_prescription.presentation_code)::text ~~ '0601012V0%'::text)))
Rows Removed by Filter: 10036400
Planning time: 6.054 ms
Execution time: 16898.366 ms
Hier ist die link to the explain.
Kann jemand vorschlagen, wie ich diese Abfragen beschleunigen könnte? Ich verstehe nicht wirklich, warum Postgres den frontend_prescription_idx_date_and_code
Index benutzt, wenn der frontend_prescription_by_practice_and_code
Index eine varchar Option hat, die Dinge schneller machen sollte.
Vielleicht würde es helfen, wenn ich einen dreispaltigen Index erstellen würde?
Sie möchten einen Index für alle drei Spalten (Datum, Übungs_ID, Code). – Thilo
Sie könnten dies vielleicht auch beschleunigen, indem Sie einen Bereich für den Code hinzufügen: 'AND presentation_code zwischen '0601012' und '0601013''. – Thilo