次の2つのテーブルがMySQL(簡体字)にあります。インデックスを使用していないJOINを使用したMySQLクエリ
clicks
(InnoDBの)- が
- が
date_added
列にインデックスが約70,000,000レコードを周りに含まれてい links
テーブル
内のレコードを参照する列
links
(MyISAM)- 約65,000
link_id
を持っています
の周りに、私はこれらのテーブルを使用して、いくつかの分析クエリを実行しようとしている、はるかに少ないレコードが含まれています。 2つの指定された日付の中で発生したクリックについて、いくつかのデータを取り出す必要があります。他のユーザーが選択したフィルタを他のテーブルを使用してリンクテーブルに追加します。
しかし、私の質問はインデックスの使用を中心に展開されています。次のクエリを実行すると、
私は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 |
+----+-------------+--------+-------+---------------+------------+---------+------+---------+--------------------------+
、私は私のlinks
テーブル内LEFT JOIN
私は、クエリを実行するのに非常に長い時間がかかることがわかり:6.50秒で完了し
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';
。あなたはインデックスが大きなテーブルに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
列で使用されていなかったことがわかりEXPLAIN
を使用します。これは他のテーブルに参加するとさらに悪化するようです。
クリックの表のdate_added
列のインデックスを使用するために何ができるのか誰にも分かりますか?
編集
私はちょうど別の方法を使用して、データベースの外に私の統計情報を取得しようとしました。私の方法の最初のステップは、クリックテーブルから別のセットのlink_id
を引き出すことです。私は、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
にインデックスを使用して、引き出すことが期待さ
distinct link_id
値。なぜこれが起こっているのか?私はlink_id
のインデックスとdate_added
を持っています。
クエリの出力時間を短縮するのに役立つクリックテーブルのlink_idに**インデックス**を追加してください。 –
@SumanEStatic - 'INDEX(link_id)'はヘルプではありません。 –
MyISAMを使用しているような匂いがします。 'SHOW CREATE TABLE'を提供してください。 –