1

2000 万レコードの mysql テーブル Stop_Times があります。

このテーブルには MyISAM ストレージ エンジンを使用しています。

私のテーブル構造は

| agency_id           | varchar(50) | NO   |     | NULL    |       |
| trip_id             | varchar(50) | NO   | PRI | NULL    |       |
| arrival_time        | time        | NO   |     | NULL    |       |
| departure_time      | time        | NO   |     | NULL    |       |
| stop_id             | varchar(50) | NO   | PRI | NULL    |       |
| stop_sequence       | int(11)     | NO   | PRI | NULL    |       |
| route_id            | varchar(50) | NO   |     | NULL    |       |
| route_type          | int(5)      | NO   |     | NULL    |       |
+---------------------+-------------+------+-----+--------

show create table Stop_Timesの出力は -

CREATE TABLE `Stop_Times` (
 `agency_id` varchar(50) NOT NULL,
 `trip_id` varchar(50) NOT NULL,
 `arrival_time` time NOT NULL,
 `departure_time` time NOT NULL,
 `stop_id` varchar(50) NOT NULL,
 `stop_sequence` int(11) NOT NULL,
 `route_id` varchar(50) NOT NULL,
 `route_type` int(5) NOT NULL,
 UNIQUE KEY `idx_Stop_Times` (`agency_id`,`trip_id`,`stop_sequence`,`stop_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
/*!50100 PARTITION BY KEY (stop_id)
PARTITIONS 250 */

1つのクエリがあります

select distinct trip_id, stop_sequence from Stop_Times where agency_id = ? and stop_id = ?

テーブルを分割する前に、このクエリには 4 ~ 5 分以上かかりました。

しかし今、私はキーによるパーティション(stop_id)のよう にstop_idでテーブルをパーティション分割しました

現在、このクエリの実行には 2 ~ 3 秒かかります。

上記のクエリが続く別のクエリがあります-

select distinct(stop_id) from Stop_Times where agency_id = ? and trip_id = ? and stop_sequence > ? 

上記のクエリでの説明の出力は次のとおりです-

1   SIMPLE  Stop_Times  range   idx_Stop_Times  idx_Stop_Times  308 NULL    250 Using where; Using index; Using temporary

このクエリにはさらに 90 ~ 150 秒かかります。

私の質問は、 trip_id と stop_sequence に Index を作成する必要がありますか? これにより、クエリのパフォーマンスが向上しますか?

一度に複数のユーザーからこのテーブルに対して多くの読み取り (選択クエリ) があるため、ストレージ エンジンを InnoDB の MyISAM から変更する必要がありますか?

データベースの達人が私を助けてください。

ありがとうございました

4

2 に答える 2

1

おそらく、このデータセットをシャーディングすることを検討したいと思うでしょう。

私は、すべてのシャードを並行してクエリできるShard-Queryというツールを維持しています。現在 KEY パーティショニングに使用している自然なシャーディング キー (stop_id) があります。Shard-Query を使用すると、この同じ列を HASH パーティショニングで使用できるため、同等の機能が得られます。

Shard-Query を使用すると、それぞれが同じテーブルのコピーを持つ 250 のデータベースを作成します。これは、250 個のパーティションに相当します。

パーティションの削除
最初のクエリを実行すると、Shard-Query は指定された stop_id を含むパーティションにのみクエリを送信します。これは、MySQL パーティションのプルーニングと同じです。

超並列処理 (MPP) 2 番目のクエリでは、実行するギアマン (メッセージ キュー) ワーカーの数に基づいて
、シャード クエリがパーティションを並行してスキャンします。16 コアのマシンを使用している場合、すべてのパーティションの MySQL のシングル スレッド スキャンの代わりに、パーティション全体で 16 度の並列処理を取得できます。

サーバーに並列処理を処理するためのリソースがある限り、並列スキャンによって大幅な速度の向上が見られます。そうでない場合は、データを N 個のサーバーに分割し (これは MPP では大規模です)、ノードを追加すると線形スケーリングが得られます。HASH パーティショニングを使用している場合、シャードを追加または削除するにはすべてのデータを再読み込みする必要があるため、これは頻繁に行わないでください。

1 つの注意点:
Shard-Query は COUNT(DISTINCT) をサポートしていますが、SELECT DISTINCT はサポートしていません。GROUP
BY を使用するようにクエリを書き直すだけです。

クエリ #1

select trip_id, stop_sequence from Stop_Times where agency_id = ? and stop_id = ? group by trip_id, stop_sequence;

クエリ #2

select stop_id from Stop_Times where agency_id = ? and trip_id = ? and stop_sequence > ? group by stop_id;
于 2012-07-31T20:32:23.793 に答える
1

にカバリング インデックスを作成します(agency_id, trip_id, stop_sequence, stop_id)。インデックス内の列の順序が重要であることに注意してください。別の順序を使用すると、効率が低下する場合があります。

于 2012-07-27T07:03:29.907 に答える