Индексы MySQL для таблицы InnoDB - не работает, верно? - PullRequest
1 голос
/ 17 ноября 2011

Я читаю книгу «Высокопроизводительный MySQL» и возиться с новой базой данных, проверяя кое-что.

Хотя я не уверен, что делаю что-то не так ..

У меня есть таблицаназывается table_users

Структура:

ID(Integer)
FullName(Char)
UserName(Char)
Password(Char)
SecurityID(TinyINT)
LocationID(TinyINT)
Active(TinyINT)

Мои индексы таковы:

PRIMARY : ID
FullName : UNIQUE : FullName
FK_table_users_LocationID (foreign key reference) : INDEX : LocationID
FK_table_users_SecurityID (foreign key reference) : INDEX : SecurityID
Active : INDEX : Active

Все они BTREE

При чтении книги,Я пытаюсь использовать следующий оператор mysql для просмотра дополнительных функций, связанных с оператором SELECT

EXPLAIN
SELECT * FROM table_users WHERE
FullName = 'Jeff';

Независимо от того, на что указывает оператор WHERE с этим вызовом, дополнительный результат - это либо ничто, либо использование where.Если я выбираю ID ... WHERE FullName = 'Jeff', он возвращает Используя где, Используя Индекс.Но не всякий раз, когда я делаю SELECT FullName .... WHERE FullName = 'Jeff' ..

Я совсем не знаком с индексами и пытаюсь немного обернуться вокруг них, немного путаясь с этим.Разве они не должны возвращать Используя индекс, если я ссылаюсь на индексированный столбец?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 17 ноября 2011

Использование индекса не означает, что это, кажется, значит.Посмотрите на индексы покрытия.Если он говорит «использование индекса», это означает, что mysql может вернуть данные для вашего запроса, не читая фактические строки.SELECT * - сможет использовать покрывающий индекс только в том случае, если в индексе есть даже столбец таблицы.Обычно это не так.

Кажется, я помню главы в High Performance Mysql, в которых говорится о покрытии индексов и о том, как читать результаты EXPLAIN.

1 голос
/ 17 ноября 2011

Какую версию MySQL вы используете?Вот тест, который я провел на Percona Server 5.5.16:

mysql> create table table_users ( 
  id int auto_increment primary key, 
  fullname char(20), 
  username char(20), 
  unique key (fullname)
);
Query OK, 0 rows affected (0.03 sec)

mysql> insert into table_users values (default, 'billk', 'billk');
Query OK, 1 row affected (0.00 sec)

mysql> explain select * from table_users where fullname='billk'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: table_users
         type: const
possible_keys: fullname
          key: fullname
      key_len: 21
          ref: const
         rows: 1
        Extra: 
1 row in set (0.00 sec)

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

mysql> explain select fullname from table_users where fullname='billk'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: table_users
         type: const
possible_keys: fullname
          key: fullname
      key_len: 21
          ref: const
         rows: 1
        Extra: Using index
1 row in set (0.00 sec)

Как и ожидалось, он может получить столбец полного имени из индекса полного имени, так что это запрос только для индекса.

mysql> explain select id from table_users where fullname='billk'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: table_users
         type: const
possible_keys: fullname
          key: fullname
      key_len: 21
          ref: const
         rows: 1
        Extra: Using index
1 row in set (0.00 sec)

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

mysql> explain select fullname, username from table_users where fullname='billk'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: table_users
         type: const
possible_keys: fullname
          key: fullname
      key_len: 21
          ref: const
         rows: 1
        Extra: 
1 row in set (0.00 sec)

Как только список выбора включает в себя любой столбец, который не является частью индекса, он можетбольше не будет запрос только для индекса.Сначала он ищет в BTREE полное имя, чтобы найти значение первичного ключа.Затем он использует это значение идентификатора, чтобы пройти BTREE для кластеризованного индекса, как InnoDB хранит всю таблицу.Там он находит другие столбцы для данной строки, включая имя пользователя.

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