繁体   English   中英

Postgres似乎使用了错误的索引?

[英]Postgres seems to be using the wrong index?

我正在使用Postgres 9.4。 这是我的桌子:

                                       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)

这是我的查询:

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')

这是输出:

 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

这是解释链接

有人可以建议我如何加快这些查询的速度吗? frontend_prescription_by_practice_and_code索引具有varchar选项时,Postgres为什么使用frontend_prescription_idx_date_and_code索引,这会使事情变得更快,所以我真的不明白。

如果我创建三列索引,这可能会有所帮助?

对于此查询:

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');

最好的索引是frontend_prescription(practice_id, processing_date, presentation_code, total_items)上的复合索引。 最后一列不是严格必需的。 它使索引成为查询的覆盖索引; 换句话说,查询所需的所有信息都在索引中,因此数据页不是必需的。

前两列可以采用任何顺序,因为where子句使用相等性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM