Составной индекс имеет направление в MySQL? - PullRequest
1 голос
/ 23 марта 2010

Когда будет необходимо следующее:

create index i_t_a_b on t(a,b);

create index i_t_b_a on t(b,a);

Ответы [ 2 ]

2 голосов
/ 23 марта 2010

Если вы хотите получить максимальную скорость извлечения и иметь оба столбца в соединении или в определенных условиях, НО иногда столбец a имеет более высокую избирательность, а иногда столбец b имеет более высокую избирательность, и вы хотите извлечь выгоду из этого факта из одного индекса.

Кроме того, я думаю, что ваше соотношение размера данных / производительности машины должно быть достаточно высоким, и в то же время вам придется (догадываясь) назвать любое улучшение необходимостью (даже хотя бы на несколько процентов).

Тем не менее, опыт учит, что все зависит от многих факторов; с конкретными СУБД и средами приложений вам лучше запускать собственные тесты.

EDIT: Дальнейшее объяснение составных индексов. из википедии :
"Порядок, в котором столбцы перечислены в определении индекса, важен. Можно получить набор идентификаторов строк, используя только первый индексированный столбец. Однако это невозможно или эффективно (в большинстве баз данных) получить набор идентификаторов строк, использующих только второй или больший индексированный столбец.
Например, представьте телефонную книгу, которая организована сначала по городу, затем по фамилии, а затем по имени. Если вам указан город, вы можете легко извлечь список всех телефонных номеров этого города. Тем не менее, в этой телефонной книге было бы очень утомительно найти все номера телефонов для данной фамилии. Вы должны искать в разделе каждого города записи с этой фамилией. "

Объяснения Википедии, возможно, чрезмерно упрощены, но они дают вам основную идею (поскольку аналогии помнят, что телефонные книги обычно имеют кластерные индексы и это не будет вашим общим индексом базы данных).

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

Ах, подумал о лучшей аналогии с примером, который вы ищете Представьте себе хороший учебник, в котором будет оглавление с главами и подразделами, а также количество страниц, на которых они находятся (это некластеризованный индекс, который содержит указатели на записи данных - страницы). Теперь представьте, что учебник по стандарту SQL-92, тогда большинство терминов в оглавлении будут терминами SQL (придерживайтесь этого предположения). У вас также будет другой указатель в конце книги, в котором будут перечислены все интересные термины в алфавитном порядке (предположим, с названиями основных глав) и номера страниц.

На такой вопрос, как «Скажите мне все главы, под которыми появляется DISTINCT», вы бы использовали второй индекс. (потому что селективность более позднего поля высока)

На такой вопрос, как «Скажите мне количество терминов, которые появляются в первой главе», вы бы использовали TOC

Так что для таких вопросов, как Описан ли SELECT в главе DML? Вы можете использовать любой из индексов. (потому что селективность обоих полей высокая) Однако, если TOC самого DML имеет длину 3 страницы, а запись SELECT в индексе содержит только пятнадцать строк, вы, вероятно, перейдете ко второй, и это пример того, когда вы получаете преимущества от обоих индексов.

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

Как я уже говорил, все планирование в порядке, но в конце запустите свои собственные тесты.

1 голос
/ 23 марта 2010

Не думаю, что есть какой-то реальный случай, когда вам это нужно.

Это может иметь смысл, когда в вашей таблице гораздо больше столбцов, a и b не являются уникальными, и вам нужна высокая производительность при выполнении обоих следующих запросов:

Select Max(b) From t Where a=1  --# Would use i_t_a_b

и

Select Max(a) From t Where b=1  --# Would use i_t_b_a

Допустим, ваш стол выглядит так:

a  b  c  d  e
-  -  -  -  -
0  8  x  x  x
0  9  x  x  x
1  8  x  x  x
1  9  x  x  x

i_t_a_b выглядит примерно так:

0
  8
  9
1
  8
  9

i_t_b_a выглядит примерно так:

8
  0
  1
9
  0
  1

Select Max(b) From t Where a=1

придется искать в 8 и 9 из i_t_b_a, чтобы найти все строки с a=1. Это все еще намного быстрее, чем сканирование полной таблицы (нужно также прочитать все x), но это не так быстро, как использование i_t_a_b.

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