数百万レコード(14,000,000)の単純なテーブルがあり、単純なクエリでは「データの送信」に時間がかかりすぎています。
テーブル
CREATE TABLE IF NOT EXISTS details (
id int(11) NOT NULL,
date date NOT NULL,
time int(2) NOT NULL,
minutes_online decimal(5,0) NOT NULL,
minutes_playing decimal(5,0) NOT NULL,
minutes_chatting decimal(5,0) NOT NULL,
minutes_away decimal(5,0) NOT NULL
PRIMARY KEY (id,date,time)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
簡単なクエリ
mysql> SELECT * FROM details WHERE id = 3014595;
説明する
mysql> EXPLAIN SELECT * FROM details WHERE id = 3014595;
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | details | ref | PRIMARY | PRIMARY | 4 | const | 1482 | |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
クエリのプロファイル
mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000024 |
| checking query cache for query | 0.000078 |
| checking permissions | 0.000014 |
| Opening tables | 0.000126 |
| System lock | 0.000011 |
| Table lock | 0.000030 |
| init | 0.000027 |
| optimizing | 0.000117 |
| statistics | 0.040077 |
| preparing | 0.000029 |
| executing | 0.000006 |
| Sending data | 7.536960 |
| end | 0.000013 |
| query end | 0.000004 |
| freeing items | 0.000037 |
| storing result in query cache | 0.000006 |
| logging slow query | 0.000003 |
| cleaning up | 0.000006 |
+--------------------------------+----------+
ご覧のとおり、SELECT
ステートメントはインデックスを使用し、1482行のみを読み取りました。それでも、クエリは7.536960秒かけてデータを送信しました。これは、クエリが必要とするより多くの行を読み取るようです。
これは単純なクエリで、わずか7フィールド(行平均59バイト)であり、ファンシー関数はありません。これを引き起こしている可能性のあるアイデアはありますか?
注:idはユーザーIDです。各ユーザーは、毎日の1時間ごとに少なくとも1つのエントリを持つことができます。したがって、IDは一意ではありません。
編集:同じ構造とはるかに多くの行(3400万)を持つ別のテーブルがあります。この大きなテーブルで同じクエリを実行すると、1秒未満で結果が返されます。
唯一の違いは、大きいテーブルは小さいテーブルほど多くのクエリを取得しないことです。
- クエリの数がプロセスを遅くしている可能性はありますか?MySQLキャッシュはオンです。また、CakePHPはクエリの数を減らすためにクエリをキャッシュします。
- テーブルが保存されているファイルが破損しているなどの可能性はありますか?
アップデート この問題は、データ層をWeb層から分離することで解決されました。データ層もRAMがアップグレードされ、raid10で実行されています。
1591 rows in set (16.48 sec)
もう一度クエリを実行しました。これが、期間が異なる理由です。今から16秒かかりました(!!)
SELECT
戻りますか?