0

Есть много вопросов по этой теме, но все они, кажется, более сложные случаи, чем то, на что я смотрю в данный момент, и ответы не кажутся применимыми.postgres не использует индекс

OHDSI=> \d record_counts 
       Table "results2.record_counts" 
     Column   |   Type   | Modifiers 
------------------------+-----------------------+----------- 
concept_id    | integer    | 
schema     | text     | 
table_name    | text     | 
column_name   | text     | 
column_type   | text     | 
descendant_concept_ids | bigint    | 
rc      | numeric    | 
drc     | numeric    | 
domain_id    | character varying(20) | 
vocabulary_id   | character varying(20) | 
concept_class_id  | character varying(20) | 
standard_concept  | character varying(1) | 
Indexes: 
    "rc_dom" btree (domain_id, concept_id) 
    "rcdom" btree (domain_id) 
    "rcdomvocsc" btree (domain_id, vocabulary_id, standard_concept) 

Стол имеет 3,133,778 записи, поэтому Postgres не должен быть игнорирование индекса из-за малого размера таблицы.

I фильтр на Domain_ID, который индексируется, а индекс игнорируется:

OHDSI=> explain select * from record_counts where domain_id = 'Drug'; 
           QUERY PLAN 
------------------------------------------------------------------------ 
Seq Scan on record_counts (cost=0.00..76744.81 rows=2079187 width=87) 
    Filter: ((domain_id)::text = 'Drug'::text) 

Я выключаю seqscan и:

OHDSI=> set enable_seqscan=false; 
SET 
OHDSI=> explain select * from record_counts where domain_id = 'Drug'; 
            QUERY PLAN 
------------------------------------------------------------------------------------- 
Bitmap Heap Scan on record_counts (cost=42042.13..105605.97 rows=2079187 width=87) 
    Recheck Cond: ((domain_id)::text = 'Drug'::text) 
    -> Bitmap Index Scan on rcdom (cost=0.00..41522.33 rows=2079187 width=0) 
     Index Cond: ((domain_id)::text = 'Drug'::text) 

Действительно, план говорит, что это будет дороже использовать индекс, чем нет, но почему? Если индекс позволяет обрабатывать гораздо меньше записей, не следует ли быстрее использовать его?

+0

Текущая статистика в вашей стране? –

+0

BTW: У таблицы нет первичного ключа? – joop

+0

@ MikeSherrill'CatRecall ': Я запускал 'анализ record_counts'. Есть что-то еще, что мне нужно сделать? – Sigfried

ответ

2

Хорошо, похоже, что Postgres знал, что он делает. Особое значение индексированного столбца, которое я использовал («Drug»), составляло 66% строк в таблице. Итак, да, фильтр делает набор строк значительно меньшим, но поскольку эти строки будут разбросаны между страницами, индекс не позволяет их быстрее получать.

OHDSI=> select domain_id, count(*) as rows, round((100 * count(*)::float/3133778.0)::numeric,4) pct from record_counts group by 1 order by 2 desc; 
     domain_id  | rows | pct 
---------------------+---------+--------- 
Drug    | 2074991 | 66.2137 
Condition   | 466882 | 14.8984 
Observation   | 217807 | 6.9503 
Procedure   | 165800 | 5.2907 
Measurement   | 127239 | 4.0602 
Device    | 29410 | 0.9385 
Spec Anatomic Site | 28783 | 0.9185 
Meas Value   | 10415 | 0.3323 
Unit    | 2350 | 0.0750 
Type Concept  | 2170 | 0.0692 
Provider Specialty | 1957 | 0.0624 
Specimen   | 1767 | 0.0564 
Metadata   | 1689 | 0.0539 
Revenue Code  |  538 | 0.0172 
Place of Service |  480 | 0.0153 
Race    |  467 | 0.0149 
Relationship  |  242 | 0.0077 
Condition/Obs  |  182 | 0.0058 
Currency   |  180 | 0.0057 
Condition/Meas  |  115 | 0.0037 
Route    |  81 | 0.0026 
Obs/Procedure  |  78 | 0.0025 
Condition/Device |  52 | 0.0017 
Condition/Procedure |  25 | 0.0008 
Meas/Procedure  |  25 | 0.0008 
Gender    |  19 | 0.0006 
Device/Procedure |  9 | 0.0003 
Meas Value Operator |  9 | 0.0003 
Visit    |  8 | 0.0003 
Drug/Procedure  |  3 | 0.0001 
Spec Disease Status |  3 | 0.0001 
Ethnicity   |  2 | 0.0001 

Когда я использовать любое другое значение в предложении где (в том числе «Состояние», с 15% строк), Postgres делает использование индекса.

(Несколько удивительно, что даже после того, как я скопировал таблицу на основе индекса domain_id, она по-прежнему не использует индекс при фильтрации на «Drug», но улучшение производительности для фильтрации 34% строк не имеет значения, t, похоже, стоит продолжить это.)

+1

Для условия, которое возвращает 66% всех строк, индексный поиск никогда не будет быстрее, чем сканирование seq. Поскольку поиск по индексу требует 3-4 операций ввода-вывода ** для строки ** (произвольный доступ). См. здесь: http://stackoverflow.com/a/5203827/330315 –

Смежные вопросы