2014-10-23 6 views
1

Если у меня есть большой стол с:Каков правильный способ индексирования таблицы postgres при выполнении запроса с двумя полями?

varchar foo 
integer foo_id 
integer other_id 
varchar other_field 

И я мог бы делать запросы, как:

select * from table where other_id=x 

очевидно, мне нужен индекс other_id, чтобы избежать сканирования таблицы.

Если я и делаю:

select * from table where other_id=x and other_field='y' 

Хочу ли я еще один индекс на other_field или что отходы, если я никогда не делать:

select * from table where other_field='y' 

т.е. я использую только other_field с other_id вместе в запросе.

Будет ли улучшен составной индекс как [other_id, other_field]? Или это вызовет сканирование таблицы для первого простого запроса?

ответ

2

Используйте EXPLAIN and EXPLAIN ANALYZE, если вы еще не используете эти два. После того, как вы поймете основы плана запросов, вы сможете эффективно оптимизировать запросы к базе данных.

Теперь на вопрос - говорить что-либо, не зная немного о значении, может ввести в заблуждение. Если значений не существует, то будет достаточно простого индекса other_id. Если есть много значений other_field (т. Е. Тысяч), я бы подумал о создании составного индекса.

Хочу ли я еще один индекс на other_field или что отходы, если я никогда не делать:

Да, это было бы очень вероятно трата пространства. Postgres - able to combine two indexes, но условия для этого должны быть в порядке.

Будет ли улучшен составной индекс как [other_id, other_field]?

Возможно.

Или это вызовет сканирование таблицы для первого простого запроса?

Postgres может использовать индекс с несколькими столбцами только для первого столбца (не совсем верно - проверьте ответы на комментарии).

Основное правило - получить реальный набор данных, подготовить запросы, которые вы пытаетесь оптимизировать. Запустите EXPLAIN ANALYZE по этим запросам. Попробуйте переписать их (т. Е. Соединяется вместо подзапросов или наоборот) и проверьте производительность (EXPLAIN ANALYZE). Попытайтесь добавить индексы, которые, по вашему мнению, могут помочь и проверить производительность (EXPLAIN ANALYZE) ... если это не поможет, не забудьте отказаться от ненужного индекса.

И если у вас все еще есть проблемы, и ваш набор данных большой (десятки миллионов +), вам может потребоваться пересмотреть даже выполнение определенных запросов. Может потребоваться другой подход (например,пакетная/асинхронная обработка) или другая технология для конкретной задачи.

+0

спасибо, это очень помогло. Я буду отмечать этот ответ лучше всего, когда SO позволяет мне. –

+0

В значительной степени переписан ответ. Были некоторые ошибки :). –

+0

вы все равно выигрываете :) –

0

Если other_id отличается высокой степенью избирательности, вам может не понадобиться индекс на other_field. Если только несколько строк соответствуют индексу other_id=x, глядя на каждого из них, чтобы увидеть, соответствуют ли они также other_field=y, возможно, он будет достаточно быстрым, чтобы не беспокоиться об увеличении индексов.

Если выяснится, что вам нужно сделать запрос быстрее, то вы почти наверняка хотите составной индекс. Отдельный индекс на other_field вряд ли поможет.

0

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

Давайте посмотрим, какие индексы удовлетворяют которые ИНЕКЕ в запросах:

       {other_id} {other_id, other_field} {other_field, other_id} {other_field} 
other_id=x      yes  yes      no      no 
other_id=x and other_field='y' partially yes      yes      partially 
other_field='y'    no   no      yes      yes 

Таким образом, чтобы удовлетворить все 3 ИНЕКЕ, вам нужно:

  • либо индекс {other_id} и составной индекс на {other_field, other_id}
  • или индекс на {other_field} и составной индекс на {other_id, other_field}
  • или составной индекс на {other_id , other_field} и составной индекс на {other_field, other_id}.

В зависимости от распределения ваших данных, вы можете также получить прочь с {other_id} и {other_field}, но вы должны тщательно измерить, прежде чем выбор в пользу этого решения. Кроме того, вы можете рассмотреть вопрос о замене * с более узким набором полей, а затем covering их индексами, но это совсем другая тема ...


«жирнее» решение, чем два других - рассмотреть только если у вас есть конкретные потребности покрытия.

+0

Операция op утверждает, что третий запрос никогда не используется. Правильное принятие правильного ответа – MatBailie

+0

@MatBailie Darn, я пропустил это! Благодарю. –