5

したがって、ここに非常に単純なテーブル 'tbl' があります。

+---------+---------------------+------+-----+---------+----------------+
| Field   | Type                | Null | Key | Default | Extra          |
+---------+---------------------+------+-----+---------+----------------+
| val     | varchar(45)         | YES  | MUL | NULL    |                |
| id      | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
+---------+---------------------+------+-----+---------+----------------+

そしてそれのためのインデックス:

+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table  | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| tbl    |          0 | PRIMARY  |            1 | id          | A         |   201826018 |     NULL | NULL   |      | BTREE      |         |
| tbl    |          1 | val      |            1 | val         | A         |      881336 |     NULL | NULL   | YES  | BTREE      |         |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

私はこの単純な選択を試みています:

select val from tbl where val = 'iii';

結果: セット内の 86208 行 (0.08 秒)

しかし、少し変更したい場合:

select id, val from tbl where val = 'iii';

結果は次のとおりです: セットで 86208 行 (47.30 秒)

私は、どこを指すかというカウントの権利を持っています。私が変更しているのは、結果の行の表現だけです。なぜこれほどまでに恐ろしい遅延が発生するのでしょうか。(この遅延を毎回再現することはできないと言わざるを得ません。「reset query cache」または「query_cache_type=off」コマンドを設定した後でも、すぐに実行できます)。

4

3 に答える 3

3

サーバー構成を実際に調べないとわかりませんが、これは経験に基づいた推測です。最初の例では、MySQL は実際にテーブル データを読み取らずにクエリを満たすことができます。あなたが求めたすべての情報は、インデックスだけから取得できます。インデックスのカーディナリティはval10 6行程度であり、インデックス内の行は非常に短くなることに注意してください。

2 番目のケースでは、 のインデックスにないデータを要求していますval。ここで、エンジンは実際にデータから行を見つけて読み取る必要があります。ここでは、カーディナリティは約 250 倍大きく、インデックスは の順序で行を取得するためval、対応する値を見つけるにはid、ディスク上の数百ギガのデータを大量にジャンプする必要があります。これは非常に遅くなります。

于 2012-06-10T00:24:13.527 に答える
0

ORDER BYaと `LIMIT をクエリに追加してみてください。それは大いに役立つはずです。

クエリをこれに変更すると、より高速になると思います。

select id, val from tbl where val = 'iii' order by val limit 10;
于 2012-06-09T20:33:37.793 に答える
0

2 つの列に基づいて選択を行っていますが、両方のインデックスが存在しません。id と valの両方で構成される新しいインデックスを追加してみてください。

于 2012-06-09T20:42:04.943 に答える