これを見た:「col1ORcol2」を使用してmysqlでインデックスを使用できますか? しかし、議論を単純かつ的確に保つために、この関連する質問をすることができると思いました。
私は2つのテーブルを持っています:lists
とagree_and_disagree_count
。
lists
テーブルには2つのtimestamp
フィールドmodified_on
とがありfirst_publish_date
ます。これらのフィールドには両方とも独自のインデックスがあります。
agree_and_disagree_count
テーブルにはtimestamp
フィールドもありdate_created
、これもインデックスが付けられます。
同じテーブルのフィールドに関する次のORステートメントでは、両方のインデックスが使用されます。
mysql> EXPLAIN SELECT * FROM lists l
-> WHERE (l.modified_on > '2013-01-07 12:50:51' OR
-> l.first_publish_date > '2013-01-07 12:50:51')\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: l
type: index_merge
possible_keys: modifiedon,first_publish_date
key: modifiedon,first_publish_date
key_len: 4,9
ref: NULL
rows: 2
Extra: Using sort_union(modifiedon,first_publish_date); Using where
ただし、フィールドが異なるテーブルからのものである場合、インデックスは使用されていないように見えます。
mysql> EXPLAIN SELECT * FROM lists l
-> JOIN agree_and_disagree_count adc ON adc.list_id=l.list_id
-> WHERE (l.modified_on > '2013-01-07 12:50:51' OR
-> adc.date_created > '2013-01-07 12:50:51')\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: adc
type: ALL
possible_keys: list_id_type_id,idx_list_id,idx_date_created
key: NULL
key_len: NULL
ref: NULL
rows: 5114907
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: l
type: eq_ref
possible_keys: PRIMARY,modifiedon
key: PRIMARY
key_len: 4
ref: adc.list_id
rows: 1
Extra: Using where
なんで?
コメントに適切にフォーマットされた返信を入力する方法がわからないので、以下は私を助けてくれた@Iserniへの返信です。
私は次のことをしました:
use test;
-- create tables
create table lists (
list_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
modified_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
first_publish_date DATETIME NULL DEFAULT NULL,
primary key (list_id)
) ENGINE=InnoDB;
create table agree_and_disagree_count (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
list_id int unsigned not null,
date_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
primary key (id)
) ENGINE=InnoDB;
-- create indices
create index index_modified_on on lists (modified_on);
create index index_first_publish_date on lists (first_publish_date);
create index index_data_created on agree_and_disagree_count (date_created);
-- load data
insert into lists (list_id, modified_on, first_publish_date) values
(1, now(), now()),
(2, now(), now()),
(3, now(), now());
insert into agree_and_disagree_count (list_id, date_created) values
(1, now()), (1, now()), (2, now());
-- query
EXPLAIN SELECT * FROM lists l JOIN agree_and_disagree_count adc
ON adc.list_id=l.list_id WHERE (l.modified_on > '2013-01-01 12:50:51'
OR adc.date_created > '2013-01-07 11:50:51');
+----+-------------+-------+------+----------------------------------+------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------------------------+------+---------+------+------+--------------------------------+
| 1 | SIMPLE | l | ALL | PRIMARY,index_modified_on | NULL | NULL | NULL | 3 | |
| 1 | SIMPLE | adc | ALL | index_data_created,index_list_id | NULL | NULL | NULL | 3 | Using where; Using join buffer |
+----+-------------+-------+------+----------------------------------+------+---------+------+------+--------------------------------+
-- create new indexes suggested by Iserni
CREATE INDEX adc_test_ndx ON agree_and_disagree_count (list_id, date_created);
CREATE INDEX l_test_ndx ON lists (list_id, modified_on);
-- query
EXPLAIN SELECT * FROM lists l JOIN agree_and_disagree_count adc
ON adc.list_id=l.list_id WHERE (l.modified_on > '2013-01-01 12:50:51'
OR adc.date_created > '2013-01-07 11:50:51');
+----+-------------+-------+-------+-----------------------------------------------+--------------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-----------------------------------------------+--------------+---------+------+------+--------------------------------+
| 1 | SIMPLE | adc | index | index_data_created,index_list_id,adc_test_ndx | adc_test_ndx | 8 | NULL | 3 | Using index |
| 1 | SIMPLE | l | ALL | PRIMARY,index_modified_on,l_test_ndx | NULL | NULL | NULL | 3 | Using where; Using join buffer |
+----+-------------+-------+-------+-----------------------------------------------+--------------+---------+------+------+--------------------------------+
フルスキャンがまだ行われているように見えますか?
受け入れられた回答の下にある@Iserniのコメントを見てください。