Индексы и многостолбцовые первичные ключи - PullRequest
27 голосов
/ 15 июня 2010

Пошёл искать и не нашел ответа на этот конкретный вопрос нуба.Приношу свои извинения, если я пропустил это.

В базе данных MySQL у меня есть таблица со следующим первичным ключом

Идентификатор PRIMARY KEY (счет-фактура, элемент)

В моем приложении ятакже будет часто выбирать «элемент» сам по себе и реже только «счет».Я предполагаю, что выиграл бы от индексов для этих столбцов.

MySQL не жалуется, когда я определяю следующее:

INDEX (счет-фактура), INDEX (элемент), идентификатор PRIMARY KEY (счет-фактура), item)

Но я не вижу никаких доказательств (используя DESCRIBE - единственный способ, которым я знаю, как выглядеть), что для этих двух столбцов были установлены отдельные индексы.

Итак,Вопрос в том, автоматически ли индексируются столбцы, составляющие первичный ключ?Кроме того, есть ли лучший способ, чем DESCRIBE, чтобы изучить структуру моей таблицы?

Ответы [ 6 ]

43 голосов
/ 15 июня 2010

Я не очень хорошо знаком с внутренностями индексов в mySql, но по двум знакомым мне продуктам вендоров баз данных (MsSQL, Oracle) это сбалансированные структуры дерева, узлы которых организованы в виде последовательного кортежа столбцы, по которым определен индекс ( В определенной последовательности )

Таким образом, если mySql не делает это совсем иначе (возможно, нет), любой составной индекс (для более чем одного столбца) может использоваться для любого запроса, который необходимо фильтровать или сортировать по подмножество столбцов в индексе, если список столбцов совместим, т. Е. Если столбцы, когда они упорядочены так же, как упорядоченный список столбцов в полном индексе, являются упорядоченное подмножество полного набора столбцов индекса, которое начинается в начале фактической последовательности индексов, без пропусков, кроме конца ...

Другими словами, это означает, что если у вас есть индекс для (a, b, c, d), запрос, который фильтрует по (a), (a, b) или (a, b, c), также может используйте индекс, но запрос, который нужно отфильтровать по (b), (c) или (b, c), не сможет использовать индекс ...

Так что в вашем случае, если вам часто нужно фильтровать или сортировать только по столбцу item , вам нужно добавить еще один индекс для этого столбца ...

15 голосов
/ 15 июня 2010

Я лично использую phpMyAdmin для просмотра и редактирования структуры баз данных MySQL. Это веб-приложение, но оно достаточно хорошо работает на локальном веб-сервере (для этого я запускаю на своем компьютере экземпляр apache и phpPgAdmin).

Что касается составного ключа (invoice, item), он действует как индекс для (invoice, item) и для invoice. Если вы хотите индексировать просто item, вы должны добавить этот индекс самостоятельно. Ваш PK будет отсортирован по invoice, а затем по item, где invoice одинаково в нескольких записях. Хотя порядок в составном ПК не имеет значения для обеспечения уникальности, он имеет значение для доступа.

На вашем столе я бы использовал:

PRIMARY KEY id (invoice, item), INDEX (item)
4 голосов
/ 15 июня 2010

Чтобы вернуть информацию индекса таблицы, вы можете использовать:

SHOW INDEX FROM <table>;

См .: http://dev.mysql.com/doc/refman/5.0/en/show-index.html

Для просмотра информации таблицы:

SHOW CREATE TABLE <table>;

См: http://dev.mysql.com/doc/refman/5.0/en/show-create-table.html

Первичные ключи являются индексами, поэтому нет необходимости создавать дополнительные индексы.Вы можете найти больше информации о них в синтаксисе CREATE TABLE (здесь слишком много для вставки):

http://dev.mysql.com/doc/refman/5.0/en/create-table.html

3 голосов
/ 15 июня 2010

Я не очень знаком с MySQL, но, как правило, многостолбцовый индекс одинаково полезен для первого столбца индекса как индекс только для этого столбца. Индекс с несколькими столбцами становится менее полезным для запросов к одному столбцу, чем дальше столбец появляется в индексе.

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

Например, если у вас есть следующая таблица:

Col1 |Col2 |Col3
----------------
   A |   1 |   Z
   A |   2 |   Y
   A |   2 |   X
   B |   1 |   Z
   B |   2 |   X

Предполагая, что у вас есть индекс для всех трех столбцов, по порядку дерево будет выглядеть примерно так:

A
+-1
  +-Z
+-2
  +-X
  +-Y
B
+-1
  +-Z
+-2
  +-X

Искать Col1 = 'A' легко: вам нужно только взглянуть на 2 упорядоченных значения. Однако, чтобы разрешить col3 = 'X', вы должны просмотреть все значения в 4 больших сегментах, каждое из которых упорядочено по отдельности.

2 голосов
/ 04 апреля 2017

Существует разница между составным индексом и составным первичным ключом. Если вы определили составной индекс, как показано ниже

INDEX idx(invoice,item)  

индекс не будет работать, если вы делаете запрос на основе item и вам нужно добавить отдельный индекс

INDEX itemidx(item)  

Но, если вы определили составной первичный ключ, как показано ниже

PRIMARY KEY(invoice, item)  

индекс будет работать, если вы делаете запрос на основе item, и отдельный индекс не требуется.

Рабочий пример:

mysql>create table test ( col1 int(20), col2 int(20) ) primary key(col1,col2);
mysql>explain select * from test where col2 = 1;
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
|  1 | SIMPLE      | test  | index | NULL          | PRIMARY | 8       | NULL |   10 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
0 голосов
/ 11 февраля 2019

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

Если вы используете mysql workbench, вы можете вручную щелкнуть схему правой кнопкой мыши и щелкнуть на edit, чтобы увидеть все о таблице

...