10Mから500Mの大きな行数を持つMyISAMテーブルがあります。テーブルは時系列データをまれに格納するために使用されており、私はのために最適化したいと思います。これは、エポックと分類子列(数千のカテゴリを含む)の2つのインデックスです。MySQL - テーブルインデックスまたはテーブルデータへのアクセスが遅い
私の問題は、SQL_NO_CACHE
を使用していても、特定のカテゴリの最初のSELECT
はかなり長く(10〜50秒)、次のものは本当に高速です。このようなクエリは通常、100,000〜1Mの要素を返します。
プロファイリングでは、MySQLが「送信データ」に多くの時間を費やしていることがわかります。これは、多くの時間がディスクI/Oを実行していることを示します。しかし、私は実際にボトルネックがどこにあるのか分かりません:
- BTREEのボトルネックは読んでいますか?ツリーは、選択されたノード内に数千個のノードしかなく、1Mポイント未満しかありません。古い学校のハードドライブを使っていても、現代のマシンでは30秒かかるとは思えません。
- テーブルの行を読み取っていますか?それは〜40bytesの平均長さを持つ百万行未満です。
- 他に何かを考慮していないのですか?ここで
クエリの結果は次のとおりです。
mysql> SELECT SQL_NO_CACHE COUNT(`Time`) FROM archive_1 WHERE Channel=63;
+---------------+
| COUNT(`Time`) |
+---------------+
| 450619 |
+---------------+
1 row in set (28.67 sec)
mysql> SELECT SQL_NO_CACHE COUNT(`Time`) FROM archive_1 WHERE Channel=63;
+---------------+
| COUNT(`Time`) |
+---------------+
| 450619 |
+---------------+
1 row in set (2.20 sec)
mysql> SELECT SQL_NO_CACHE COUNT(`Time`) FROM archive_1 WHERE Channel=63;
+---------------+
| COUNT(`Time`) |
+---------------+
| 450619 |
+---------------+
1 row in set (0.88 sec)
mysql> SHOW PROFILES;
+----------+-------------+-----------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+-------------+-----------------------------------------------------------------------------------+
| 1 | 28.66720725 | SELECT SQL_NO_CACHE COUNT(`Time`) FROM archive_1 WHERE Channel=63 |
| 2 | 2.19872350 | SELECT SQL_NO_CACHE COUNT(`Time`) FROM archive_1 WHERE Channel=63 |
| 3 | 0.87811475 | SELECT SQL_NO_CACHE COUNT(`Time`) FROM archive_1 WHERE Channel=63 |
+----------+-------------+-----------------------------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> SHOW PROFILE FOR QUERY 1;
+----------------------+-----------+
| Status | Duration |
+----------------------+-----------+
| starting | 0.000113 |
| checking permissions | 0.000010 |
| Opening tables | 0.000027 |
| System lock | 0.000017 |
| init | 0.000030 |
| optimizing | 0.000018 |
| statistics | 0.055731 |
| preparing | 0.000024 |
| executing | 0.000008 |
| Sending data | 28.611161 |
| end | 0.000019 |
| query end | 0.000005 |
| closing tables | 0.000014 |
| freeing items | 0.000021 |
| logging slow query | 0.000003 |
| logging slow query | 0.000004 |
| cleaning up | 0.000005 |
+----------------------+-----------+
17 rows in set (0.00 sec)
mysql> SHOW PROFILE FOR QUERY 2;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000105 |
| checking permissions | 0.000011 |
| Opening tables | 0.000036 |
| System lock | 0.000015 |
| init | 0.000028 |
| optimizing | 0.000019 |
| statistics | 0.032255 |
| preparing | 0.000024 |
| executing | 0.000007 |
| Sending data | 2.166140 |
| end | 0.000020 |
| query end | 0.000004 |
| closing tables | 0.000014 |
| freeing items | 0.000025 |
| logging slow query | 0.000003 |
| cleaning up | 0.000018 |
+----------------------+----------+
16 rows in set (0.00 sec)
mysql> SHOW PROFILE FOR QUERY 3;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000071 |
| checking permissions | 0.000009 |
| Opening tables | 0.000018 |
| System lock | 0.000012 |
| init | 0.000021 |
| optimizing | 0.000014 |
| statistics | 0.000059 |
| preparing | 0.000020 |
| executing | 0.000007 |
| Sending data | 0.877795 |
| end | 0.000021 |
| query end | 0.000004 |
| closing tables | 0.000015 |
| freeing items | 0.000029 |
| logging slow query | 0.000015 |
| cleaning up | 0.000006 |
+----------------------+----------+
16 rows in set (0.00 sec)
私が照会しています特定のテーブルには、4237427600バイトのデータ長と4255541248バイトのインデックス長と107407213個の行が含まれています。私は昨日それを最適化しました。
クエリがI/Oバウンドの場合は、いつでもSSDに切り替えることができます。また、タイムインデックスをダブルではなく整数として格納するオプションもあります。しかし、これまでのところ私はボトルネックがどこにあるのか分からず、もっと知る前に大きな変化を避けたいと思っています。
初めてクエリを実行すると、キャッシュに何もありません.2回目にキャッシュにデータがあるため、クエリの実行は高速です。 – xachela