8

私は非常に単純なクエリを持っています:

  SELECT   comments.*
  FROM comments 
  WHERE comments.imageid=46

そして、これは私のテーブルです:

CREATE TABLE IF NOT EXISTS `comments` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `imageid` int(10) unsigned NOT NULL DEFAULT '0',
  `uid` bigint(20) unsigned NOT NULL DEFAULT '0',
  `content` text CHARACTER SET utf8,
  `adate` datetime DEFAULT NULL,
  `ip` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `ids` (`imageid`) USING BTREE,
  KEY `dt` (`adate`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=12 ;

しかし、MySql はこの単純なクエリでインデックスを使用できません。説明結果は次のとおりです。

id  select_type     table   type    possible_keys   key     key_len     ref     rows    filtered    Extra
1   SIMPLE  comments    ALL     ids     NULL    NULL    NULL    4   75.00   Using where

クエリをこれに変更している間、Mysql はインデックスを使用できます。なんで?:

  SELECT   comments.id
  FROM comments 
  WHERE comments.imageid=46

ここに説明があります:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    filtered    Extra
1   SIMPLE  comments    ref     ids     ids     4   const   4   100.00  Using index
4

3 に答える 3

8

「comments」テーブルの行が少ないと思います。これが、最初のクエリでインデックスを使用する代わりに、MySQL が完全なテーブル スキャンを行っている理由です。全テーブル スキャンのコストは、最初にインデックスを照合してから行を検索するよりも低くなる可能性があると推定されています。

2 番目のクエリではインデックスを使用しています。これは、クエリのすべての列 (「id」列) をインデックスから直接取得できるため、インデックスを照合した後にテーブルの行を検索する必要がありません。これが「インデックスを使用する」追加情報の意味です。

「コメント」にかなりの数の行がある場合、MySQL がまだフル スキャンを使用しているかどうか試してみてください。これは奇妙な動作になると思います。実際、MySQL バージョン 5.1 でまったく同じことをテストしましたが、行数が少なくても常に「インデックス」を使用しています。

于 2012-04-15T09:42:45.210 に答える
1

2番目のクエリは、インデックスでカバーされたクエリです。要求された情報全体をインデックスから読み取ることができます(主キーはInnoDBのセカンダリインデックスの一部であるため)。

最初のクエリでは、MySQLはインデックスからPKを読み取り、次に行を読み取る必要があります。テーブルの行数が非常に少ないため、オプティマイザは、行を直接読み取り、一致しない行を破棄すると高速になると判断します。

于 2012-04-15T11:06:47.327 に答える
1

標準的 なものを試してみましたか?

于 2012-04-15T08:54:17.333 に答える