1

以下を考えると -

drop table if exists learning_indexes;

create table learning_indexes (
    id INT NOT NULL,
    col1 CHAR(30),
    col2 CHAR(30),
    col3 CHAR(30), 
    PRIMARY KEY (id),
    index idx_col1 (col1),
    index idx_col1_col2 (col1,col2)
);

explain

select
    col1,col2
from
    learning_indexes
where
    col1 = 'FOO'
    and col2 = 'BAR'

MySQL が idx_col1_col2 よりも idx_col1 を選択するのはなぜですか?

+----+-------------+------------------+------+------------------------+----------+---------+-------+------+-------------+
| id | select_type | table            | type | possible_keys          | key      | key_len | ref   | rows | Extra       |
+----+-------------+------------------+------+------------------------+----------+---------+-------+------+-------------+
|  1 | SIMPLE      | learning_indexes | ref  | idx_col1,idx_col1_col2 | idx_col1 | 91      | const |    1 | Using where |
+----+-------------+------------------+------+------------------------+----------+---------+-------+------+-------------+

これは私のバージョン情報です -

+-------------------------+---------------------+
| Variable_name           | Value               |
+-------------------------+---------------------+
| innodb_version          | 1.1.8               |
| protocol_version        | 10                  |
| slave_type_conversions  |                     |
| version                 | 5.5.29              |
| version_comment         | Source distribution |
| version_compile_machine | i386                |
| version_compile_os      | osx10.7             |
+-------------------------+---------------------+
4

2 に答える 2

0

MySQL が時々間違ったインデックスを選択するという Floaf に同意しますが、ここではそうではないと思います。MySQL は、行数とデータ構造を考慮して、選択するインデックスを決定します。

このようなかなり単純なクエリの場合、テーブルに含まれる行が約 100 行未満であるか空の場合、MySQL はインデックスをまったく使用しない可能性があります。インデックスを使用するよりも、すべてのテーブル行をスキャンする方が計算コストが低いようです。説明計画では、「キー」列には idx_col1 と表示されていますが、「エクストラ」列には「インデックスの使用」とは表示されていません。

テーブルに約 100 行を超える行が含まれている場合、MySQL は idx_col1 の使用を開始します。説明計画はこれを示します。col1 に文字列 'FOO' を実際に含む約 100 行を超える行がある場合にのみ、MySQL は idx_col1 を使用しても一時的な結果セットが十分に削減されないことに気付きます。 col2 の BAR'。したがって、idx_col1_col2 に切り替わります。

MySQL がどのインデックスを使用するかをどのように迅速に決定するかは完全にはわかりませんが、ヒューリスティックとインデックス内の個々の行のカーディナリティ、つまりインデックス付きの行がどれだけ「選択的」であるかに関係があると思います。

于 2013-04-09T18:29:51.683 に答える
0

ここであなたのケースを説明することはできませんが、MySQL が単に「間違った」インデックスを選択することがあります。おそらく、データベースは十分に小さいため、この場合は何の違いもないと理解できます。

このクエリは非常に単純であるため、どのインデックスが最も適切かを理解する必要があります。

経験上、クエリがより複雑になり、特にテーブルが非常に大きくなると、MySQL は (ランダムに?) 別のインデックスを選択してそれを使用することを決定し、クエリは 0.01 秒から 100 秒以上になることがあります。したがって、どのインデックスが正しいかわかっている場合は、FORCE INDEX() を使用します。USE INDEX() を使用しても、MySQL は別のインデックスを選択して、クエリ速度にさまざまな悪影響を与えることがあります。

于 2013-04-09T18:04:41.323 に答える