0

私は次のmysqlクエリを持っています

select points_for_user from items where user_id = '38415';

クエリについて説明すると、これが返されます

id  select_type table   type    possible_keys   key                     key_len ref     rows    Extra
1   SIMPLE      items   index   NULL            points_for_user_index   2       NULL    1000511 Using index

問題は、インデックスのために、行数をテーブルの行数よりもはるかに少なくするべきではないかということです。

user_idはプライマリインデックスなので、points_for_userだけでインデックスを作成してみましたが、それでもすべての行を調べます。user_id AND points_for_userのインデックスは、引き続きすべての行を検索します。

私は何が欠けていますか?

ありがとう!

CREATE TABLE IF NOT EXISTS `items` (
  `capture_id` int(11) NOT NULL AUTO_INCREMENT,
  `id` int(11) NOT NULL,
  `creator_user_id` bigint(20) NOT NULL DEFAULT '0',
  `user_id` int(11) NOT NULL,
  `accuracy` int(11) NOT NULL,
  `captured_at` timestamp NOT NULL DEFAULT '2011-01-01 06:00:00',
  `ip` varchar(30) NOT NULL,
  `capture_type_id` smallint(6) NOT NULL DEFAULT '0',
  `points` smallint(6) NOT NULL DEFAULT '5',
  `points_for_user` smallint(6) NOT NULL DEFAULT '3',
  PRIMARY KEY (`capture_id`),
  KEY `capture_user` (`capture_id`,`id`,`user_id`),
  KEY `user_id` (`user_id`,`id`),
  KEY `id` (`id`),
  KEY `capture_creator_index` (`capture_id`,`creator_user_id`),
  KEY `points_capture_index` (`points_for_user`,`creator_user_id`),
  KEY `points_for_user_index` (`points_for_user`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1008992 ;

select count(*) from items where user_id = '38415'

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  captures    ref user_munzee_id  user_munzee_id  4   const   81  Using index
4

1 に答える 1

0

mysqlオプティマイザは、クエリ中に可能な限り最高のインデックスを使用しようとします。

最初のクエリで、オプティマイザはpoints_for_user_indexが最良の選択であると考えています。実際、Extra列には「Usingindex」ステータスが表示されます。これは「Coveringindex」を意味します。

「カバーするインデックス」は、クエリに必要なすべてのフィールド(この場合は...からpoints_for_userを選択)がインデックスに含まれている場合に発生します。これにより、完全なmysqlデータ(.MYD)へのアクセスが回避され、インデックスへの直接アクセスが優先されます。 (.MYI)

まず、インデックスツリー分析テーブルの再構築を試みることができます

表の項目を分析します。

非常に大きなテーブルに関する注意

ANALYZE TABLEは、テーブルのキー分布を分析して保存します。分析中、テーブルはInnoDBとMyISAMの読み取りロックでロックされます。このステートメントは、InnoDB、NDB、およびMyISAMテーブルで機能します。MyISAMテーブルの場合、このステートメントはmyisamchk--analyzeを使用するのと同じです。

「問題」が解決せず、オプティマイザーの選択をバイパスしたい場合は、明示的にインデックスの使用を強制することができます

EXPLAIN SELECT points_for_user FROM items USE INDEX ( user_id ) WHERE user_id = '38415'

詳細:http ://dev.mysql.com/doc/refman/5.5/en/index-hints.html

クリスチャン

于 2012-08-27T06:28:19.533 に答える