设为首页 加入收藏

TOP

MySQL之索引原理(三)
2018-12-12 22:08:46 】 浏览:178
Tags:MySQL 索引 原理
AL ] INDEX 索引名 (字段名[(长度)] [ASC
|DESC]) ; #删除索引:DROP INDEX 索引名 ON 表名字;

  示范代码

#方式一
create table t1(
    id int,
    name char,
    age int,
    sex enum('male','female'),
    unique key uni_id(id),
    index ix_name(name) #index没有key
);


#方式二
create index ix_age on t1(age);

#方式三
alter table t1 add index ix_sex(sex);

#查看
mysql> show create table t1;
| t1    | CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  `name` char(1) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` enum('male','female') DEFAULT NULL,
  UNIQUE KEY `uni_id` (`id`),
  KEY `ix_name` (`name`),
  KEY `ix_age` (`age`),
  KEY `ix_sex` (`sex`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

  四、正确使用索引

  首先,我们得有一个认识,建立索引确实可以帮助我们加速查询,而且可以建立辅助索引,但并不是说我们把每个字段都给加上辅助索引然后就会很方便,其实在索引存在很多的时候,会让应用程序的性能受到影响,在建立多少索引这问题上,应该找到一个平衡点。

  其次,在我们添加了索引以后并不是一定查找速度就很快,这和我们如何去查找有关,比如下面几种情况:

  1,范围问题、或者条件不明确,条件中出现这些符号或关键字:>,<,>=,<=,!=,between  and 

  出现上面的情况相当于不是精确查找,而是给的一个范围或者是模糊查找,这导致查找的时候还得去一一进行比较,所以效率也不高,当我们查找的范围越大时,肯定是越慢的,当查找范围越小时,肯定是越快的

  2,like

  当查找条件中出现like时,若没有%,_符号时,如‘xx’就是精确查找,速度很快的;当有符号时,当符号在前时,如‘%xx’,根据最左匹配原则,肯定先匹配%,由于%代表任意字符,所以会导致把所有的数据都要匹配一下,这效率没有提高;但当符号在后就不一样了,如‘xx%’,根据最左匹配原则,先匹配上xx,此时就可以把很多给直接排除,导致速度也很快。

  3,尽量选择区分度高的字段作为索引,比如我们选择性别作为索引,不是男的就是女的,在查询的时候回得到很多数据,这样也会很慢,而且没有实际意义

我们编写存储过程为表s1批量添加记录,name字段的值均为egon,也就是说name这个字段的区分度很低(gender字段也是一样的,我们稍后再搭理它)

回忆b+树的结构,查询的速度与树的高度成反比,要想将树的高低控制的很低,需要保证:在某一层内数据项均是按照从左到右,从小到大的顺序依次排开,即左1<左2<左3<...

而对于区分度低的字段,无法找到大小关系,因为值都是相等的,毫无疑问,还想要用b+树存放这些等值的数据,只能增加树的高度,字段的区分度越低,则树的高度越高。极端的情况,索引字段的值都一样,那么b+树几乎成了一根棍。本例中就是这种极端的情况,
name字段所有的值均为'egon' #现在我们得出一个结论:为区分度低的字段建立索引,索引树的高度会很高,然而这具体会带来什么影响呢??? #1:如果条件是name='xxxx',那么肯定是可以第一时间判断出'xxxx'是不在索引树中的(因为树中所有的值均为'egon’,看第一条的时候就知道你不在索引树里面了),所以查询速度很快 #2:如果条件正好是name='egon',查询时,我们永远无法从树的某个位置得到一个明确的范围,只能往下找,往下找,往下找。。。这与全表扫描的IO次数没有多大区别,所以速度很慢

  4,索引最好不要参与计算,比如把条件写成where id*3=3000,这样相当于每次都要把id拿来计算一下才比,把所有数据都过一遍,很慢的,但我们写成where id = 3000/3,条件是一样的,但销量就高很多

  5,and,or

#1、and与or的逻辑
    条件1 and 条件2:所有条件都成立才算成立,但凡要有一个条件不成立则最终结果不成立
    条件1 or 条件2:只要有一个条件成立则最终结果就成立

#2、and的工作原理
    条件:
        a = 10 and b = 'xxx' and c > 3 and d =4
    索引:
        制作联合索引(d,a,b,c)
    工作原理:  #如果是你找的话,你会怎么找,是不是从左到右一个一个的比较啊,首先你不能确定a这个字段是不是有索引,即便是有索引,也不一定能确保命中索引了(所谓命中索引,就是应用上了索引),mysql不会这么笨的,看下面mysql是怎么找的:
        索引的本质原理就是先不断的把查找范围缩小下来,然后再进行处理,对于连续多个and:mysql会按照联合索引,从左到右的顺序找一个区分度高的索引字段(这样便可以快速锁定很小的范围),加速查询,即按照d—>a->b->c的顺序

#3、or的工作原理
    条件:
        a = 10 or b = 'xxx' or c > 3 or d =4
    索引:
        制作联合索引(d,a,b,c)
        
    工作原理:
        只要一个匹配成功就行,所以对于连续多个or:mysql会按照条件的顺序,从左到右依次判断,即a->b->c->d

  五、联合索引与覆盖索引

  1,联合索引

  联合索引就是把表的多个字段合起来作为一个索引。

mysql> create table t(
    -> a int,
    -> b int,
    -> primary key(a),
    -> key idx_a_b(a,b)
    -> );
Query OK, 0 rows affected (0.11 sec)

  上图就是一个联合索引的数据结构图,是按照(a,b)的顺序进行了存放。

  select * from t1 where a=2 and b=1;这是可以使用联合索引加速查询的

  select * from t1 where a=3;这也可以用联合索引加速查询的,可以看出是按a排序的

  但是,select * from t1 where b=2;这是不能使用联合索引加速查询的,因为不是按b排序,从上到下,从左到右,b的值都是乱的

  注意:建立联合索引时,把区分度高的放在前面,即最左边,依次排下去,范围查询放在后面

  联合索引第二好处:第一个字段的值相同时,就已经对第二个字段的值进行了排序,上图中的a为1时,b的值从左往右增大的,排好序了的

create table buy_log(
    userid int unsigned not null,
    buy_date date
);

insert into buy_log values
(1,'2009-01-01'),
(2,'2009-01-01'),
(3,'2009-01-01'),
(1,'2009-02-01'),
(3,'2009-02-01'),
(
首页 上一页 1 2 3 4 5 6 下一页 尾页 3/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇python的部分内置函数 下一篇python面向对象之抽象工厂设计模式

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目