MySQL запрос с JOIN не использует INDEX
У меня есть следующие две таблицы в MySQL (упрощенный).
clicks
(ЬшоВВ)Содержит около 7000000 записейИмеет индекс наdate_added
колонкаИмеет колонкуlink_id
который относится к записи вlinks
Таблицаlinks
(MyISAM)Содержит гораздо меньше записей, около 65 000Я пытаюсь выполнить некоторые аналитические запросы, используя эти таблицы. Мне нужно вытащить некоторые данные о кликах, которые произошли внутри двух указанных дат, при применении фильтров, выбранных другими пользователями, с использованием других таблиц и их соединении с таблицей ссылок.
Однако мой вопрос вращается вокруг использования индексов. Когда я запускаю следующий запрос:
SELECT
COUNT(1)
FROM
clicks
WHERE
date_added >= '2016-11-01 00:00:00'
AND date_added <= '2016-11-03 23:59:59';
Я получаю ответ обратно в 1.40 сек. С помощьюEXPLAIN
Я считаю, что MySQL использует индекс наdate_added
колонка как и ожидалось.
EXPLAIN SELECT COUNT(1) FROM clicks WHERE date_added >= '2016-11-01 00:00:00' AND date_added <= '2016-11-16 23:59:59';
+----+-------------+--------+-------+---------------+------------+---------+------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+-------+---------------+------------+---------+------+---------+--------------------------+
| 1 | SIMPLE | clicks | range | date_added | date_added | 4 | NULL | 1559288 | Using where; Using index |
+----+-------------+--------+-------+---------------+------------+---------+------+---------+--------------------------+
Тем не менее, когда яLEFT JOIN
в моемlinks
В таблице я считаю, что выполнение запроса занимает гораздо больше времени:
SELECT
COUNT(1) AS clicks
FROM
clicks AS c
LEFT JOIN links AS l ON l.id = c.link_id
WHERE
c.date_added >= '2016-11-01 00:00:00'
AND c.date_added <= '2016-11-16 23:59:59';
Который завершен за 6,50 сек. С помощьюEXPLAIN
Я считаю, что индекс не был использован наdate_added
колонка:
EXPLAIN SELECT COUNT(1) AS clicks FROM clicks AS c LEFT JOIN links AS l ON l.id = c.link_id WHERE c.date_added >= '2016-11-01 00:00:00' AND c.date_added <= '2016-11-16 23:59:59';
+----+-------------+-------+--------+---------------+------------+---------+---------------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+------------+---------+---------------+---------+-------------+
| 1 | SIMPLE | c | range | date_added | date_added | 4 | NULL | 6613278 | Using where |
| 1 | SIMPLE | l | eq_ref | PRIMARY | PRIMARY | 4 | c.link_id | 1 | Using index |
+----+-------------+-------+--------+---------------+------------+---------+---------------+---------+-------------+
Как вы можете видеть, индекс не используется дляdate_added
столбец в большей таблице и, кажется, занимает гораздо больше времени. Это кажется еще хуже, когда я присоединяюсь к другим таблицам.
Кто-нибудь знает, почему это происходит, или я могу что-то сделать, чтобы заставить его использовать индекс наdate_added
столбец в таблице кликов?
редактировать
Я только что попытался получить мою статистику из базы данных, используя другой метод. Первый шаг в моем методе включает в себя выделение определенного набораlink_id
s из таблицы кликов. Я обнаружил, что я снова вижу ту же проблему, без JOIN. Индекс не используется:
Мой запрос:
SELECT
DISTINCT(link_id) AS link_id
FROM
clicks
WHERE
date_added >= '2016-11-01 00:00:00'
AND date_added <= '2016-12-05 10:16:00'
Этот запрос занял почти минуту. Я побежалEXPLAIN
на этом и обнаружил, что запрос не использует индекс, как я ожидал, будет:
+----+-------------+---------+-------+---------------+----------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+----------+---------+------+----------+-------------+
| 1 | SIMPLE | clicks | index | date_added | link_id | 4 | NULL | 79786609 | Using where |
+----+-------------+---------+-------+---------------+----------+---------+------+----------+-------------+
Я ожидал, что он будет использовать индекс наdate_added
отфильтровать набор результатов, а затем вытянутьlink_id
ценности. Есть идеи, почему это происходит? У меня есть индекс наlink_id
так же какdate_added
.