2013-06-04 3 views
14

Скажите, у меня есть таблица ResidentInfo, и в этой таблице у меня есть уникальные ограничения HomeAddress, который является VARCHAR. Для будущего запроса я добавлю индекс в этот столбец. Запрос будет иметь только операцию =, и я буду использовать шаблон B-TREE, так как в настоящее время шаблон Hash не рекомендуется.postgresql index on string column

Вопрос: С точки зрения эффективности, используя B-TREE, как вы думаете, я должен добавить новый столбец с цифрами 1,2,3 ...., N, соответствующий разному homeaddress, и вместо добавления индекса на HomeAddress, Я должен добавить индекс в столбец чисел?

Я задаю этот вопрос, потому что не знаю, как работает индекс.

+0

Спасибо за @Denis, указав, что уникальное ограничение автоматически установит индекс. – Hao

+0

В соответствии с характеристикой существует одно правило, которое всегда применяется: проверьте его. Невозможно получить все ваши данные из такого неопределенного описания, поэтому, когда вы спрашиваете о скорости, проверьте, что для вас наиболее быстро. Бывают случаи, когда теоретически субоптимальный подход быстрее для данных, которые вы обычно обрабатываете. – omikron

ответ

23

Для простых проверок равенства (=), индекс B-дерева на столбце varchar или text является простым и лучшим выбором. Это, безусловно, помогает производительности много.

Конечно, индекс B-Tree на простом integer работает лучше. Во-первых, сравнение простых значений integer немного быстрее. Но что более важно, производительность также зависит от размера индекса. Большая колонка означает меньшее количество строк на странице данных, что означает, что нужно читать больше страниц ...

Поскольку HomeAddress вряд ли уникален, это не является хорошим естественным первичным ключом. Я бы настоятельно рекомендовал вместо этого использовать первичный ключ суррогата . A serial column - очевидный выбор для этого. Его единственная цель - иметь простой, быстрый первичный ключ для работы.

Если у вас есть другие таблицы, ссылающиеся на указанную таблицу, это становится еще более эффективным. Вместо дублирования длинной строки для столбца внешнего ключа вам нужен только 4 байта для целочисленного столбца. И вам не нужно так много каскадно обновлять обновления, так как адрес должен меняться, а суррогатный pk может оставаться неизменным (но не обязательно, конечно).

Ваша таблица может выглядеть следующим образом:

CREATE TABLE resident (
    resident_id serial PRIMARY KEY 
    ,address text NOT NULL 
    -- more columns 
); 

CREATE INDEX resident_adr_idx ON resident(address); 

В результате двух индексов B-Tree. Уникальный индекс на resident_id и простой индекс на address.

More about indexes in the manual.
Postgres предлагает множество опций - но вам больше не нужен этот простой случай.

+0

Большое вам спасибо! Это действительно помогает! Таким образом, два индекса B-Tree собираются ускорить запросы типа «SELECT * FROM resident WHERE resident_id = xxxxx;» а также дать мне вариант в случае, если я должен запросить использование адреса, я прав? – Hao

+0

@ Хао: Правильно. Кроме того, оба индекса поддерживают более простые проверки равенства. –

+0

Спасибо! Как вы уже упоминали, в отношении операций B-TREE индекс Hash Pattern Index EnterpriseDB по-прежнему имеет недостатки прямо сейчас, и я могу переключиться на Hash Pattern после их исправления, поскольку я использую только операцию «=» для запроса. Принимает O (1) для Hash и O (nlogn) для B-Tree. – Hao

5

В Postgres уникальное ограничение обеспечивается путем сохранения уникального индекса в поле, поэтому вы уже закрыты.

В случае, если вы решите ограничение уникальности на адрес плох (который, если честно, это: что супруг создать отдельный счет о flatshares и т.д.?), Вы можете создать так:

create index on ResidentInfo (HomeAddress); 
+0

О, спасибо, что указали это!Но вопрос все еще остается. Будет ли запрос ускоряться, если я добавлю столбец чисел и использую его вместо адреса? – Hao