Много комментариев в том же духе, но я подумал, что дам подробный ответ.Я собираюсь использовать одну из моих собственных таблиц / баз данных здесь для объяснения.Давайте возьмем этот запрос:
SELECT A.id, B.asin FROM AmazonWishlistItems A LEFT JOIN AmazonWishlistItemPrices B ON (B.asin = A.asin) WHERE A.asin LIKE "%C%"
Этот запрос возвращает около 851 и занимает 0,5 секунды.Если мы добавим слово EXPLAIN
к запросу, MySQL сообщит нам, что делает этот запрос.
mysql> EXPLAIN SELECT A.id, B.asin FROM AmazonWishlistItems A LEFT JOIN AmazonWishlistItemPrices B ON (B.asin = A.asin) WHERE A.asin LIKE "%C%";
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | A | ALL | NULL | NULL | NULL | NULL | 1183 | Using where |
| 1 | SIMPLE | B | ALL | NULL | NULL | NULL | NULL | 6594 | |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
2 rows in set (0.00 sec)
Важным столбцом для просмотра здесь является rows
, так как это количество записей, которые MySQL имеетПри этом нужно искать таблицы A и B, и в этом случае приходится искать все строки, хотя есть только 851, которые соответствуют условию.Вот как таблицы могут быстро выйти из-под контроля, для поиска можно использовать только 6594 записи, но если оставить их в покое, это может легко достичь ваших 1,5 миллионов строк.
Таким образом, мы можем сократить это, добавив индекс к таблице., позволяя MySQL хранить ссылку для каждой записи.
ALTER TABLE AmazonWishlistItemPrices ADD INDEX idx_asin (asin)
Это просто говорит о создании индекса с именем idx_asin
и использовании столбца asin
для индексации.Если мы снова запустим наш EXPLAIN ...
mysql> EXPLAIN SELECT A.id, B.asin FROM AmazonWishlistItems A LEFT JOIN AmazonWishlistItemPrices B ON (B.asin = A.asin) WHERE A.asin LIKE "%C%";
+----+-------------+-------+------+---------------+----------+---------+---------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+----------+---------+---------------------+------+-------------+
| 1 | SIMPLE | A | ALL | NULL | NULL | NULL | NULL | 1183 | Using where |
| 1 | SIMPLE | B | ref | idx_asin | idx_asin | 12 | mah_database.A.asin | 6 | Using index |
+----+-------------+-------+------+---------------+----------+---------+---------------------+------+-------------+
2 rows in set (0.00 sec)
У нас осталось шесть строк, и вы можете увидеть в possible_keys
наш индекс наш.Вы можете обнаружить, что с определенными объединениями и пунктами where ваши индексы игнорируются, это просто MySQL, говорящий «Мне все равно придется получать все данные» из-за условий, которые вы предоставили в условии WHERE
.
Лучше всего использовать числовые ключи для индексации, вы можете обойтись без некоторых varchars, но они занимают место на диске.Вы должны иметь PRIMARY KEY
на каждом столе, где это возможно.Итак, посмотрите на структуру вашей базы данных и подумайте о добавлении некоторых индексов.
Последнее, что нужно проверить, есть ли в вашей таблице индексы, вы можете использовать SHOW CREATE TABLE
, за которым следует имя таблицы.