Heim > Datenbank > MySQL-Tutorial > 关于mysql中or条件和索引

关于mysql中or条件和索引

WBOY
Freigeben: 2016-06-01 13:16:40
Original
1260 Leute haben es durchsucht
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 = "melbourne"and loc_id != 10
Nach dem Login kopieren
     低效: 
select loc_id , loc desc , region from location where loc_id = 10 or region = "melbourne"
Nach dem Login kopieren

如果你坚持要用OR, 那就需要返回记录最少的索引列写在最前面.

通过查询表中值得分布情况(看看where条件的各个分支对应的数据基数有多大),确定那个值放在前边。select sum(loc_id = 10),sum(region="melbourne") from location/G************************1.row***********************SUM(loc_id = 10): 7992SUM(region="melbourne"): 30
Nach dem Login kopieren

通过检测发现应该把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);
Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage