Уникальный индекс по двум столбцам плюс отдельный индекс по каждому? - PullRequest
0 голосов
/ 01 февраля 2009

Я не знаю много об оптимизации базы данных, но я пытаюсь понять этот случай.

Скажите, у меня есть следующая таблица:

cities
===========
state_id integer
name varchar(32)
slug varchar(32)

Теперь, скажем, я хочу выполнить такие запросы:

SELECT * FROM cities WHERE state_id = 123 AND slug = 'some_city'
SELECT * FROM cities WHERE state_id = 123

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

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

Я работаю над PostgreSQL, но мне кажется, что этот случай настолько прост, что большинство СУБД работают аналогично.

Кроме того, я знаю, что это точно не имеет значения для маленьких столов, но мой пример прост. Подумайте о таблицах 200k + строк.

Спасибо!

Ответы [ 4 ]

1 голос
/ 01 февраля 2009

Достаточно одного уникального индекса (state_id, slug). Чтобы быть уверенным, конечно, вам нужно запустить EXPLAIN и / или ANALYZE (возможно, с помощью чего-то вроде http://explain.depesz.com/),, но в конечном итоге, какие индексы являются подходящими, зависит очень близко от того, какие запросы вы будете выполнять Помните, что индексы делают SELECT быстрее, а INSERT, UPDATE и DELETE медленнее, поэтому в идеале вам нужно только столько индексов, сколько действительно необходимо.

Кроме того, PostgreSQL имеет интеллектуальный оптимизатор запросов: он будет использовать радикально разные планы поиска для запросов к маленьким и огромным таблицам. Если таблица небольшая, она просто выполнит последовательное сканирование и даже не потрудится с любыми индексами, поскольку затраты на работу с ними выше, чем простое просеивание таблицы. Это изменится на другой план, как только размер таблицы превысит пороговое значение, и может снова измениться, если таблица снова увеличится, или вы измените свой SELECT, или ....

Резюме: вы не можете доверять результатам EXPLAIN и ANALYZE для наборов данных, которые намного меньше или отличаются от ваших фактических данных. Сделайте так, чтобы потом работали быстрее (если вам нужно).

1 голос
/ 01 февраля 2009

[РЕДАКТИРОВАТЬ: неправильно прочитал вопрос ... Надеюсь, мой ответ более актуален сейчас!]

В вашем случае я бы предложил 1 индекс на (state_id, slug). Если вам когда-нибудь понадобится выполнить поиск только по slug, добавьте индекс только для этого столбца. Если они у вас есть, то добавление другого индекса на state_id не нужно, поскольку первый индекс уже покрывает это.

Индекс можно использовать всякий раз, когда начальный сегмент его столбцов используется в предложении WHERE. Так, например индекс по столбцам A, B и C оптимизирует запросы, содержащие предложения WHERE, включающие предложения A, B и C, предложения WHERE только с A и B или предложения WHERE только с A. Обратите внимание, что порядок появления столбцов в определении индекса важно - этот пример индекса нельзя использовать для предложений WHERE, включающих только B и / или C.

(Конечно, оптимизатор запросов зависит от того, используется ли конкретный индекс на самом деле, но в вашем случае с 200 тыс. Строк, вы можете гарантировать, что простой поиск по state_id или slug или обоим будет использовать один индексов.)

1 голос
/ 01 февраля 2009

Любой приличный оптимизатор увидит индекс по трем столбцам - скажем:

CREATE INDEX idx_1 ON SomeTable(Col1, Col2, Col3);

и будет использовать этот индекс для любого из следующих условий:

WHERE Col1 = ...something...

WHERE Col1 = ...something... AND Col2 = ...otherthing...

WHERE Col3 = ....whatnot....
  AND Col1 = ...something....
  AND Col2 = ...otherthing...

То есть он будет использовать индекс, если существуют условия, применяемые к любому смежному начальному подмножеству столбцов индекса. Хотя я использовал равенство, оно также может применяться к диапазонам (например, открыто - больше, чем) или закрыто (между двумя значениями).

0 голосов
/ 01 февраля 2009

Для оптимизации используйте EXPLAIN http://www.postgresql.org/docs/7.4/static/sql-explain.html и убедитесь сами. Но оптимизация - не самая важная причина для создания этих индексов; Во-первых, это ограничение, запрещающее базе данных не быть логичным.

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