2009-12-03 2 views
1

У меня есть две таблицы:Postgresql 8.3, простой запрос не использует индекс

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 сканы во всем;)

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

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

ответ

-1

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

+1

Из-за прошлых дизайнерских решений это не всегда число –

2

Да, PostgreSQL docs может вам сообщить!

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

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

Если форсирование использование индекса не использовать индекс , то есть две возможности: либо система правильно и с использованием индекс действительно не подходит, или смета расходов планов запроса не отражает реальность. Таким образом, вы должны задать свой запрос с индексами и без них. Здесь может быть полезной команда ANPLYIN ANALYZE.

4

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

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

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

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

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

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

+0

+1 Это все о величине значений. – Trey

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