Spe*_*cer 13 mysql sql query-optimization intersect
我试图强制MySQL使用两个索引.我正在加入一个表,我想利用两个索引之间的交叉.具体术语是使用交叉,这里是MySQL文档的链接:
http://dev.mysql.com/doc/refman/5.0/en/index-merge-optimization.html
有没有办法强制执行此功能?我的查询是使用它(它加速了),但现在无论出于什么原因它已停止.
这是我想要做的JOIN.我希望查询使用的两个索引是scs.CONSUMER_ID_1和scs_CONSUMER_ID_2
JOIN survey_customer_similarity AS scs
ON cr.CONSUMER_ID=scs.CONSUMER_ID_2
AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_1
OR cr.CONSUMER_ID=scs.CONSUMER_ID_1
AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_2
Run Code Online (Sandbox Code Playgroud)
Ric*_*iwi 19
请参阅MySQL Docs FORCE INDEX.
JOIN survey_customer_similarity AS scs
FORCE INDEX (CONSUMER_ID_1,CONSUMER_ID_2)
ON
cr.CONSUMER_ID=scs.CONSUMER_ID_2
AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_1
OR cr.CONSUMER_ID=scs.CONSUMER_ID_1
AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_2
Run Code Online (Sandbox Code Playgroud)
正如TheScrumMeister在下面指出的那样,它取决于您的数据,是否可以同时使用两个索引.
使用此选项可创建一个> 100K记录的表,大约1K行与筛选器匹配i in (2,3),1K行匹配j in (2,3):
drop table if exists t1;
create table t1 (id int auto_increment primary key, i int, j int);
create index ix_t1_on_i on t1(i);
create index ix_t1_on_j on t1(j);
insert into t1 (i,j) values (2,2),(2,3),(4,5),(6,6),(2,6),(2,7),(3,2);
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i*2, j*2+i from t1;
insert into t1 (i,j) select i, j from t1;
insert into t1 (i,j) select i, j from t1;
insert into t1 (i,j) select 2, j from t1 where not j in (2,3) limit 1000;
insert into t1 (i,j) select i, 3 from t1 where not i in (2,3) limit 1000;
Run Code Online (Sandbox Code Playgroud)
做的时候:
select t.* from t1 as t where t.i=2 and t.j=3 or t.i=3 and t.j=2
Run Code Online (Sandbox Code Playgroud)
你收到8个匹配:
+-------+------+------+
| id | i | j |
+-------+------+------+
| 7 | 3 | 2 |
| 28679 | 3 | 2 |
| 57351 | 3 | 2 |
| 86023 | 3 | 2 |
| 2 | 2 | 3 |
| 28674 | 2 | 3 |
| 57346 | 2 | 3 |
| 86018 | 2 | 3 |
+-------+------+------+
Run Code Online (Sandbox Code Playgroud)
使用EXPLAIN上面的查询来获取:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | t | range | ix_t1_on_i,ix_t1_on_j | ix_t1_on_j | 5 | NULL | 1012 | Using where
Run Code Online (Sandbox Code Playgroud)
即使我们FORCE INDEX在两个索引上添加查询EXPLAIN也会返回完全相同的东西.
要使它跨两个索引收集,然后将它们相交,请使用:
select t.* from t1 as a force index(ix_t1_on_i)
join t1 as b force index(ix_t1_on_j) on a.id=b.id
where a.i=2 and b.j=3 or a.i=3 and b.j=2
Run Code Online (Sandbox Code Playgroud)
使用该查询explain来获取:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | a | range | ix_t1_on_i | ix_t1_on_i | 5 | NULL | 1019 | Using where
1 | SIMPLE | b | range | ix_t1_on_j | ix_t1_on_j | 5 | NULL | 1012 | Using where; Using index
Run Code Online (Sandbox Code Playgroud)
这证明正在使用索引.但取决于许多其他因素,这可能会或可能不会更快.
| 归档时间: |
|
| 查看次数: |
41465 次 |
| 最近记录: |