Как добавить индексы в таблицы MySQL?

308

У меня очень большая таблица MySQL с около 150 000 строк данных. В настоящее время, когда я пытаюсь запустить

SELECT * FROM table WHERE id = '1';

код работает нормально, так как поле ID является основным индексом. Однако в последнее время для разработки проекта я должен искать базу данных в другом поле. Например

SELECT * FROM table WHERE product_id = '1';

Это поле ранее не было проиндексировано, но я добавил его как индекс, но когда я пытаюсь выполнить указанный выше запрос, результаты очень медленные. Запрос EXPLAIN показывает, что нет индекса для поля product_id, когда я уже добавил его, и в результате запрос занимает от 20 минут до 30 минут, чтобы вернуть одну строку.

Мои результаты полного EXPLAIN:

| id | select_type | table | type | possible_keys        | key  | key_len | ref  | rows      | Extra       |
+----+-------------+-------+------+----------------------+------+---------+------+------+------------------+
|  1 | SIMPLE      | table | ALL  | NULL                 | NULL | NULL    | NULL |    157211 | Using where |
+----+-------------+-------+------+----------------------+------+---------+------+------+------------------+

Возможно, было бы полезно отметить, что я только что посмотрел, и поле ID хранится как INT, тогда как поле PRODUCT_ID сохраняется как VARCHAR. Может ли это быть источником проблемы?

  • 1
    Можете ли вы опубликовать полный EXPLAIN результаты? Вы уверены, что нет индекса? Или индекс есть, но MySQL решил не использовать его?
  • 150
    Большая таблица будет иметь 150 000 000 записей. Очень большая таблица содержит 15 000 000 000 записей. Таблица среднего размера имеет 150000. Для дальнейшего использования.
Показать ещё 1 комментарий
Теги:
optimization
indexing
row

7 ответов

458
ALTER TABLE `table` ADD INDEX `product_id` (`product_id`)

Никогда не сравнивайте integer с strings в MySQL. Если id - int, удалите кавычки.

  • 0
    Я уже добавил индекс, используя этот точный SQL, но кажется, что он не был «применен» к данным, и запрос EXPLAIN показывает, что для поля нет индекса.
  • 1
    Хотите проверить индекс с помощью SHOW CREATE TABLE, или вы уже сделали это?
Показать ещё 15 комментариев
128
ALTER TABLE TABLE_NAME ADD INDEX (COLUMN_NAME);
  • 89
    В MySQL, если вы используете ALTER TABLE tbl ADD INDEX (col) вместо ALTER TABLE tbl ADD INDEX col (col) ALTER TABLE tbl ADD INDEX (col) более чем один раз, то при использовании ALTER TABLE tbl ADD INDEX (col) более одного раза будут добавляться индексы с именами col_2 , col_3 , .. . каждый раз. Принимая во внимание, что использование ALTER TABLE tbl ADD INDEX col (col) второй раз, даст ERROR 1061 (42000): Duplicate key name 'col' .
55

вы можете использовать этот синтаксис для добавления индекса и управления типом индекса (HASH или BTREE)

create index your_index_name on your_table_name(your_column_name) using HASH;
or
create index your_index_name on your_table_name(your_column_name) using BTREE;

Вы можете узнать о различиях между индексами BTREE и HASH: http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html

  • 1
    Хэш конвертируется в btree, когда я вижу, используя индексы шоу.
  • 1
    Что будет по умолчанию из Hash и BTree, если я не укажу их?
Показать ещё 2 комментария
36

Стоит отметить, что несколько индексов полей могут значительно улучшить производительность вашего запроса. Таким образом, в приведенном выше примере мы предполагаем, что ProductID является единственным полем для поиска, но был запрос, чтобы сказать ProductID = 1 AND Category = 7, а затем помогает индекс нескольких столбцов. Это достигается с помощью следующего:

ALTER TABLE `table` ADD INDEX `index_name` (`col1`,`col2`)

Кроме того, индекс должен соответствовать порядку полей запроса. В моем расширенном примере индекс должен быть (ProductID, Category) не наоборот.

  • 1
    Хороший, явно названный индекс позволяет легко изменить его.
  • 0
    Можете ли вы процитировать источник the index should match the order of the query fields ?
Показать ещё 1 комментарий
20

Можно добавить индексы двух типов: когда вы определяете первичный ключ, MySQL будет считать его индексом по умолчанию

Объяснение

Первичный ключ как индекс

У вас есть таблица TBL_STUDENT и вы хотите STUDENT_ID как первичный ключ:

ALTER TABLE `tbl_student` ADD PRIMARY KEY (`student_id`)

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

Укажите имя индекса

ALTER TABLE `tbl_student` ADD INDEX student_index (`student_id`)

Вышеуказанный оператор создаст обычный индекс с именем student_index.

Создать уникальный индекс

ALTER TABLE `tbl_student` ADD UNIQUE student_unique_index (`student_id`)

Здесь student_unique_index - это имя индекса, присвоенное STUDENT_ID, и создает индекс, для которого значения должны быть уникальными (здесь может быть принят null).

Полный текст

ALTER TABLE `tbl_student` ADD FULLTEXT student_fulltext_index (`student_id`)

Выше инструкция создаст имя полного текста с student_fulltext_index, для которого вам нужен MyISAM Mysql Engine.

Как удалить индексы?

DROP INDEX `student_index` ON `tbl_student`

Как проверить доступные индексы?

SHOW INDEX FROM `tbl_student`
15

Вы говорите, что у вас есть индекс, объяснение говорит иначе. Однако, если вы действительно это делаете, это как продолжить:

Если у вас есть индекс в столбце, и MySQL решает не использовать его, это может быть вызвано тем, что:

  • Еще один индекс в запросе MySQL более подходит для использования, и он может использовать только один. Решение обычно представляет собой индекс, охватывающий несколько столбцов, если их нормальный метод поиска имеет значение более одного столбца.
  • MySQL решает, что есть много совпадающих строк, и думает, что таблицы могут быть быстрее. Если это не так, иногда помогает ANALYZE TABLE.
  • В более сложных запросах он решает не использовать его на основе чрезвычайно интеллектуального продуманного вуду в плане запроса, который по какой-то причине просто не соответствует вашим текущим требованиям.

В случае (2) или (3) вы можете уговорить MySQL использовать индекс index hint sytax, но если вы убедитесь, что запустите некоторые тесты, чтобы определить, действительно ли это повышает производительность, чтобы использовать индекс, когда вы намекаете на него.

-2

В MariaDB вы сделаете это по-другому.

CREATE INDEX index_name ON table_name (column_name);

см. документацию для дополнительных опций: https://mariadb.com/kb/en/mariadb/create-index/

Ещё вопросы

Сообщество Overcoder
Наверх
Меню