1 .where语句里面如果带有或条件,myisam表能用到索引,innodb不行。
1)myisam表:
CREATE TABLE IF NOT NOT
EXISTS`a` (`id` int(1)NOT NULL AUTO_INCREMENT,
`uid` int(11)NOT NULL,
`aNum` char(20)DEFAULT NULL,
PRIMARY KEY(`id `),
KEY`uid`(`uid`)
)ENGINE = MyISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT = 6;
mysql>解释select * from a where id = 1或uid = 2;
+ ---- + ------------- + ------- + ------------- + -------- ------- + ------------- + --------- + ------ + ------ + ---- ----------------------------------- +
| id | select_type | 表| 类型| possible_keys | 关键| key_len | ref | 行| 额外的|
+ ---- + ------------- + ------- + ------------- + -------- ------- + ------------- + --------- + ------ + ------ + ---- ----------------------------------- +
| 1 | 简单| 一个| index_merge | 主,uid | 主,uid | 4,4 | NULL | 2 | 使用union(PRIMARY,uid); 使用何处|
+ ---- + ------------- + ------- + ------------- + -------- ------- + ------------- + --------- + ------ + ------ + ---- ----------------------------------- +
1行(0.00秒)
2)innodb的表:
CREATE TABLE IF NOT EXISTS`A`(
`id` INT(1)NOT NULL AUTO_INCREMENT,
`uid` INT(11)NOT NULL,
`aNum`炭(20)DEFAULT NULL,
PRIMARY KEY(`id`),
KEY` uid`(`uid`)
)ENGINE = InnoDB DEFAULT CHARSET = latin1 AUTO_INCREMENT = 6;
mysql>解释select * from a where id = 1或uid = 2;
+ ---- + ------------- + ------- + ------ + --------------- + ------ + --------- + ------ + ------ + ------------- +
| id | select_type | 表| 类型| possible_keys | 关键| key_len | ref | 行| 额外的|
+ ---- + ------------- + ------- + ------ + --------------- + ------ + --------- + ------ + ------ + ------------- +
| 1 | 简单| 一个| 所有| 主,uid | NULL | NULL | NULL | 5 | 使用何处|
+ ---- + ------------- + ------- + ------ + --------------- + ------ + --------- + ------ + ------ + ------------- +
1行集(0.00秒)
2.必须所有的或条件都必须是独立索引:
+ ------- + ----------------------------------------- -------------------------------------------------- ---------------------------
| 表| 创建表
+ ------- + --------------------------------------- -------------------------------------------------- -----------------------------
| 一个| CREATE
TABLE`a` (`id` int(1)NOT NULL AUTO_INCREMENT,
`uid` int(11)NOT NULL,
`aNum` char(20)DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE = MyISAM AUTO_INCREMENT = 6 DEFAULT CHARSET = latin1 |
+ ------- + ----------------------------------------- -------------------------------------------------- ---------------------------
1行集(0.00秒)
说明查看:
mysql>解释select * from where where id = 1或uid = 2;
+ ---- + ------------- + ------- + ------ + --------------- + ------ + --------- + ------ + ------ + ------------- +
| id | select_type | 表| 类型| possible_keys | 关键| key_len | ref | 行| 额外的|
+ ---- + ------------- + ------- + ------ + --------------- + ------ + --------- + ------ + ------ + ------------- +
| 1 | 简单| 一个| 所有| 主要| NULL | NULL | NULL | 5 | 使用何处|
+ ---- + ------------- + ------- + ------ + --------------- + ------ + --------- + ------ + ------ + ------------- +
1排(0.00秒)
全表扫描了。
3.用UNION替换OR(适用于索引列)
通常情况下,用UNION替换WHERE子句中的OR将会起到较好的效果。对索引列使用OR将造成全表扫描。
注意,以上规则只针对多个索引列有效。如果有列没有被索引,查询效率可能会因为你没有选择OR而降低。
在下面的例子中,LOC_ID和REGION上都建有索引。
高效:
select loc_id , loc_desc , region from location where loc_id = 10
union
select loc_id , loc_desc , region from location where region = "melbourne"
低效:
select loc_id , loc desc , region from location where loc_id = 10 or region = "melbourne"
如果你坚持要用OR,那就需要返回记录最少的索引列写在最前面。
4.用于来替换或
这是一条简单易记的规则,但是实际的执行效果还须检验,在Oracle8i中下,两者的执行路径似乎是相同的。
低效:
select…. from location where loc_id = 10 or loc_id = 20 or loc_id = 30
高效的
select… from location where loc_in in (10,20,30);