Postgresql 8.3, простой запрос без индекса - PullRequest
1 голос
/ 03 декабря 2009

У меня есть две таблицы:

table1 (about 200000 records)
 number varchar(8) 

table2 (about 2000000 records)
 number varchar(8)

Поля 'число' в обеих таблицах имеют стандартные индексы. Для каждой записи в таблице 1 назначено около 10 записей в таблице 2.

Я выполняю запрос:

explain select table1.number from table1, table2 where table1.number = table2.number;

План запроса показывает, что индексы не будут использоваться, Seq сканирует все;)

Но если я уменьшу количество записей в таблице 1 до ~ 2000, план запроса начнет показывать, что индекс будет использоваться.

Может быть, кто-нибудь может сказать мне, почему postgresql ведет себя таким образом?

Ответы [ 3 ]

4 голосов
/ 03 декабря 2009

Последовательное сканирование является нормальным (и оптимальным) для запросов с очень низкой избирательностью, то есть для запросов, которые пересекают целые таблицы.

Когда вы удалили большинство строк из таблицы1, он больше не охватывал все возможные отличные значения из таблицы2 - поэтому было использовано сканирование индекса.

Для начала я бы порекомендовал попробовать этот запрос:

select * from pg_stats where tablename in ('table1','table2'); 

Это информация, которую PostgreSQL использует для создания плана запроса.

Сам планировщик довольно сложен - обратитесь к документации (упомянутой Джонатаном) и источникам [http://doxygen.postgresql.org/ -> src / backend / optimizer], если вам так любопытно.

2 голосов
/ 03 декабря 2009

Да, Документы PostgreSQL могут вам сказать!

Вот некоторые основные моменты:

Когда индексы не используются, это может быть полезно для тестирования, чтобы заставить их использовать. Есть параметры времени выполнения, которые могут отключить различные типы планов (см. Раздел 18.6.1). Например, поворот отключить последовательное сканирование (enable_seqscan) и вложенные циклы (enable_nestloop), которые являются наиболее основные планы, заставит систему используйте другой план. Если система по-прежнему выбирает последовательное сканирование или соединение с вложенным циклом, то есть вероятно, более фундаментальная причина, почему индекс не используется; за Например, условие запроса не соответствовать индексу. (Какой запрос можно использовать, какой индекс объяснено в предыдущих разделах.)

Если для принудительного использования индекса используется индекс, то есть два возможности: либо система правильно и с помощью индекса действительно не подходит или сметы из планов запроса не отражают реальность. Таким образом, вы должны время вашего запроса с индексами и без. ОБЪЯСНЕНИЕ Команда ANALYZE может быть полезна здесь.

0 голосов
/ 03 декабря 2009

Это может зависеть от того, как были созданы ваши индексы. Если «число» на самом деле число, вам следует подумать об изменении типа столбца на bigint. Опять же, не на 100% уверен, но я думаю, что индексирование по символьным столбцам работает иначе, чем по числовым полям ... Однако я мог бы говорить из моей задницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...