Ich habe die folgenden zwei Tabellen in MySQL (vereinfacht).MySQL Abfrage mit JOIN nicht mit INDEX
clicks
(InnoDB)- enthält rund etwa 70.000.000 Aufzeichnungen
- einen Index für die Spalte
date_added
Hat - enthält eine Spalte
link_id
die
links
Tabelle einen Datensatz bezieht sichlinks
(MyISAM)- enthält weit weniger Datensätze, um etwa 65.000
Ich versuche, einige analytische Abfragen mit diesen Tabellen auszuführen. Ich muss einige Daten herausnehmen, über Klicks, die innerhalb von zwei angegebenen Daten auftraten, während ich einige andere vom Benutzer ausgewählte Filter mit anderen Tabellen anwendete und sie in die Verknüpfungstabelle einfügte.
Meine Frage dreht sich jedoch um die Verwendung von Indizes. Wenn ich die folgende Abfrage ausführen:
SELECT
COUNT(1)
FROM
clicks
WHERE
date_added >= '2016-11-01 00:00:00'
AND date_added <= '2016-11-03 23:59:59';
Ich bekomme eine Antwort zurück in 1.40 sek. Using EXPLAIN
Ich finde, dass MySQL den Index auf der Spalte date_added
wie erwartet verwendet.
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 |
+----+-------------+--------+-------+---------------+------------+---------+------+---------+--------------------------+
Allerdings, wenn ich LEFT JOIN
in meinem links
Tisch finde ich, dass die Abfrage dauert viel länger auszuführen:
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';
, die in 6,50 sec abgeschlossen. Mit EXPLAIN
finde ich, dass der Index nicht auf der date_added
Spalte verwendet:
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 |
+----+-------------+-------+--------+---------------+------------+---------+---------------+---------+-------------+
Wie Sie den Index können nicht sehen, für die date_added
Spalt in dem größeren Tisch und scheint weit mehr zu nehmen verwendet. Das scheint noch schlimmer zu werden, wenn ich mich an anderen Tischen beteilige.
Weiß jemand, warum dies passiert oder ob ich irgendetwas tun kann, um den Index für die Spalte date_added
in der Clicks-Tabelle zu verwenden?
bearbeiten
Ich habe versucht, nur meine Statistiken, um aus der Datenbank eine andere Methode verwenden. Der erste Schritt in meiner Methode besteht darin, einen eindeutigen Satz von link_id
aus der Clicks-Tabelle herauszuziehen. Ich habe festgestellt, dass ich wieder das gleiche Problem sehe, ohne JOIN. Der Index wird nicht benutzt wird:
Meine Frage:
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'
Diese Abfrage dauerte fast eine Minute.Ich lief auf das eine EXPLAIN
und festgestellt, dass die Abfrage nicht den Index verwendet, wie ich es zu erwarten:
+----+-------------+---------+-------+---------------+----------+---------+------+----------+-------------+
| 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 |
+----+-------------+---------+-------+---------------+----------+---------+------+----------+-------------+
ich erwartet, dass es den Index auf date_added
verwenden würde das Ergebnis auf Filter nach unten und ziehen Sie dann die verschiedene link_id
Werte. Irgendeine Idee, warum das passiert? Ich habe einen Index auf link_id
sowie date_added
.
Fügen Sie ** index ** on link_id in den Clicks-Tabellen hinzu, die dabei helfen können, die Abfrageausgabezeit zu reduzieren –
@SumanEStatic - 'INDEX (link_id)' würde _nicht_ helfen. –
Riecht wie Sie MyISAM verwenden. Bitte geben Sie 'SHOW CREATE TABLE' an. –