0

サーバーの応答時間を250ミリ秒の範囲に抑えようとしています。ほとんどのクエリは1ミリ秒未満で完了します。これは、それ自体で長い時間がかかります。行数が多いため、1500ミリ秒を超えます。これがデータ構造です。別のクエリを使用するか、データをより速く設定する以外に、このクエリの時間を短縮するためにできることはありますか?

mysql> describe variant_bikes;

+------------+-----------------------+------+-----+---------+-------+
| Field      | Type                  | Null | Key | Default | Extra |
+------------+-----------------------+------+-----+---------+-------+
| variant_id | mediumint(8) unsigned | NO   | PRI | 0       |       |
| bike_id    | mediumint(8) unsigned | NO   | PRI | 0       |       |
+------------+-----------------------+------+-----+---------+-------+

mysql> describe cscart_product_option_variants;

+----------------------+-----------------------+------+-----+---------+----------------+
| Field                | Type                  | Null | Key | Default | Extra          |
+----------------------+-----------------------+------+-----+---------+----------------+
| variant_id           | mediumint(8) unsigned | NO   | PRI | NULL    | auto_increment |
+----------------------+-----------------------+------+-----+---------+----------------+
15 rows in set (0.00 sec)

mysql> describe bikefilter_cache;
+---------+-----------------------+------+-----+---------+----------------+
| Field   | Type                  | Null | Key | Default | Extra          |
+---------+-----------------------+------+-----+---------+----------------+
| bike_id | mediumint(8) unsigned | NO   | PRI | NULL    | auto_increment |
| year    | smallint(6) unsigned  | NO   | PRI | NULL    |                |
| make    | varchar(20)           | NO   | PRI | NULL    |                |
| line    | varchar(20)           | NO   | PRI | NULL    |                |
| model   | varchar(90)           | NO   | PRI | NULL    |                |
+---------+-----------------------+------+-----+---------+----------------+

mysql> select count(*) from variant_bikes;

+----------+
| count(*) |
+----------+
|  7577597 |
+----------+
1 row in set (1.85 sec)

mysql> select variant_id from variant_bikes where bike_id=112;
9366 rows in set (2.30 sec)

私が以前に試した1つのことは、少なくとも当時のサイズでははるかに遅いと思います。variant_bikesをそのままvariant_idのテーブルにすることでしたが、bike_idsフィールドはvarcharまたはtext、あるいはその両方であり、コンマ区切りのリストを検索しました。

私が考えるもう1つのことは、すべてのテーブルを別のより効率的なデータ構造に配置することです。

4

2 に答える 2

3

そのクエリのパフォーマンスを最高にするには、インデックスを追加しますON variant_bikes (bike_id, variant_id)

これはクエリの「カバーする」インデックスになり、MySQLはテーブルからデータブロックを参照(ルックアップ)することなく、「インデックスを使用する」ブロックのみでクエリを満たすことができます。

Q:すでにインデックスが存在するのに、なぜこのインデックスが必要なの(variant_id, bike_id)ですか?

A:インデックス内の列の順序と関係があります。クエリの述語(WHERE句)はbike_id列にあります。MySQLがインデックスを使用するには、その列がインデックスの先頭の列として表示される必要があります。

Q:(bike_id)列だけにインデックスがある場合はどうなりますか。

A: MySQLはそのインデックスを使用する可能性が非常に高いです。クエリは列から値を返す必要もありvariant_idます...最適なパフォーマンスを得るには、インデックスブロックからのクエリのみを満たす必要があります。MySQLのバージョンとストレージエンジンによっては、主キー列の値がデータブロックへの「ポインタ」であるため、MySQLはvariant_idインデックスから戻ることができる場合があります。(bike_id)

そのインデックスを追加してから実行してみるとEXPLAIN SELECT ...、最後の列(追加)として表示したいのは「インデックスの使用」です。これは、テーブルのブロックを参照しなくても、インデックスからクエリが満たされたことを示します。

... key             Extra        
--- -------------   -------------
    bike_id_index   Using index
于 2012-08-31T16:46:01.013 に答える
0

variant_bikesキーは複合キー(variant_id, bike_id)であり、その複合キーの後半を検索しています。したがって、インデックスを使用することはできません。

にインデックスを追加するbike_idと、すべてがうまくいくはずです。

于 2012-08-31T16:20:08.460 に答える