您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

关于mysql中or条件和索引

2024/2/20 19:17:13发布24次查看
1)myisam表:
mysql> explain select * from a where id=1 or uid =2;
+----+-------------+-------+-------------+---------------+-------------+---------+------+------+---------------------------------------+
| id | select_type | table | type        | possible_keys | key         | key_len | ref  | rows | extra                                 |
+----+-------------+-------+-------------+---------------+-------------+---------+------+------+---------------------------------------+
|  1 | simple      | a     | index_merge | primary,uid   | primary,uid | 4,4     | null |    2 |using union(primary,uid);using where |
+----+-------------+-------+-------------+---------------+-------------+---------+------+------+---------------------------------------+
1 row in set (0.00 sec)
在mysql5.0和更新的版本中,会同时使用这两个单列索引进行扫描,然后合并结果。索引合并需要耗费大量cpu和内存资源在算法的缓存,和并和排序上。
2)innodb表:(alter table a engine=innodb)
mysql>  explain select * from a where id=1 or uid =2;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | simple      | a     | all  | primary,uid   | null | null    | null |    5 | using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
2 .必须所有的or条件都必须是独立索引:+-------+----------------------------------------------------------------------------------------------------------------------
| table | create table
+-------+----------------------------------------------------------------------------------------------------------------------
| a     | 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 row in set (0.00 sec)
explain查看:
mysql> explain select * from a where id=1 or uid =2;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | simple      | a     | all  | primary       | null | null    | null |    5 | using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
全表扫描了。
3. 用union替换or (适用于索引列)       通常情况下, 用union替换where子句中的or将会起到较好的效果. 对索引列使用or将造成全表扫描. 
       注意, 以上规则只针对多个索引列有效. 如果有column没有被索引, 查询效率可能会因为你没有选择or而降低. 
       在下面的例子中, loc_id 和region上都建有索引.
       高效: 
select loc_id , loc_desc , region from location where loc_id = 10 union select loc_id , loc_desc , regionfrom location where region = melbourneand loc_id != 10
低效: select loc_id , loc desc , region from location where loc_id = 10 or region = melbourne
如果你坚持要用or, 那就需要返回记录最少的索引列写在最前面.
通过查询表中值得分布情况(看看where条件的各个分支对应的数据基数有多大),确定那个值放在前边。select sum(loc_id = 10),sum(region=melbourne) from location/g************************1.row***********************sum(loc_id = 10): 7992sum(region=melbourne): 30
通过检测发现应该把region=melbourne放在前边。
4. 用in来替换or  这是一条简单易记的规则,但是实际的执行效果还须检验,在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);
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product