视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
mysqlor条件可以使用目录而避免全表
2020-11-09 13:31:17 责编:小采
文档


mysql or条件可以使用索引而避免全表 在某些情况下,or条件可以避免全表扫描的。 ? 1 .where 语句里面如果带有or条件, myisam表能用到索引, innodb不行。 1)myisam表: ?CREATE TABLE IF NOT EXISTS `a` ( ? `id` int(1) NOT NULL AUTO_INCREMENT, ? `uid` i

mysql or条件可以使用索引而避免全表

在某些情况下,or条件可以避免全表扫描的。

?

1 .where 语句里面如果带有or条件, myisam表能用到索引, innodb不行。

1)myisam表:
?CREATE TABLE IF 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> 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)

2)innodb表:

CREATE TABLE IF 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=InnoDB? DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;


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上都建有索引.
? ? ? ?高效:?

?

  1. select?loc_id?,?loc_desc?,?region?from?location?where?loc_id?=?10???
  2. union???
  3. select?loc_id?,?loc_desc?,?region??from?location?where?region?=?"melbourne"???

? ? ?低效:?

  1. select?loc_id?,?loc?desc?,?region?from?location?where?loc_id?=?10?or?region?=?"melbourne"??

?

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

?

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);

?

下载本文
显示全文
专题