Начиная с версии 5.6 MySQL очень простой, хотя и длинный запрос занимает несколько порядков дольше, чем в 5.4.MySQL 5.6 long ГДЕ В запросе очень медленно
Схема: три таблицы, одна с элементами, одна с категориями и таблица M: N. Создание заявления:
CREATE TABLE element (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=4257455 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE category (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE elements_categories (
id int(11) NOT NULL AUTO_INCREMENT,
element_id int(11) NOT NULL,
category_id int(11) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY element_id (element_id,category_id),
KEY elements_categories_element_id (element_id),
KEY elements_categories_category_id (category_id),
CONSTRAINT D7d489b06a407a0c1c70f108712c815e FOREIGN KEY (category_id) REFERENCES category (id),
CONSTRAINT co_element_id_57f4f2ec0db9441c_fk_element_id FOREIGN KEY (element_id) REFERENCES element (id)
) ENGINE=InnoDB AUTO_INCREMENT=88131737 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Запрос:
SELECT elements_categories.element_id, category.id, category.name
FROM category
INNER JOIN elements_categories
ON category.id = elements_categories.category_id
WHERE elements_categories.element_id IN (1, 2, 3, ...)
Таким образом, элемент таблицы не даже играть определенную роль в этом запросе, я уже получил кучу идентификаторов из с с предыдущим запросом. (Отказ от ответственности: я использую ORM, а также вложение первого запроса не ускорял работу.) Число значений в предложении IN может стать очень большим, в моем примере 14240. Это не проблема, занимает десятую часть второй или около того. Это план выполнения:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+--------+---------------------------------------------------------------------------+------------+---------+---------------------------------+-------+--------------------------+
| 1 | SIMPLE | elements_categories | range | element_id,elements_categories_element_id,elements_categories.category_id | element_id | 4 | NULL | 42720 | Using where; Using index |
| 1 | SIMPLE | category | eq_ref | PRIMARY | PRIMARY | 4 | elements_categories.category_id | 1 | NULL |
Когда я добавляю один более элемент, время выполнения взрывается до 60 секунд плюс время получения 200 секунд. План выполнения также изменяется на это:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+------+---------------------------------------------------------------------------+---------------------------------+---------+-------------+------+-------------+
| 1 | SIMPLE | category | ALL | PRIMARY | NULL | NULL | NULL | 75 | NULL |
| 1 | SIMPLE | elements_categories | ref | element_id,elements_categories_element_id,elements_categories_category_id | elements_categories_category_id | 4 | category.id | 760 | Using where |
Диапазон и eq_ref поиски обменены на ВСЕ и реф, порядок таблиц включен, не используя elements_categories.category_id, как исх хотя внешний ключ между этими двумя таблицами. Я не понимаю, почему этот план изменился именно так.
Имеются 75 категорий и 4 300 000 элементов и 1600 000 заданий.
Я предполагаю, что я превысил ограничение по размеру здесь, но не могу понять, какой из них. Кроме того, я ничего не менял из установки MySQL 5.5, которая все время придерживалась прежнего плана выполнения.
1-й план запроса не имеет смысла для отправленного вами запроса. Это означает, что предложение where - 'elements_categories.element_id IN (1, 2, 3, ...)' или что есть дополнительные условия/join. Вы уверены, что это 'category.element_id IN ...'? – Vatev
Очень замечательно, спасибо. Ваше первое предположение верно, я изменил запрос соответствующим образом. –
Можно ли «Показать таблицу создания» для двух таблиц? Меня интересуют индексы. Также может быть интересным указание фактического размера таблиц. –