精华内容
下载资源
问答
  • mysql中每个都有一个聚簇索引(clustered index ),除此之外的上的每个非聚簇索引都是二级索引,又叫辅助索引(secondary indexes)。以innodb来说,每个innodb具有一个特殊的索引称为聚集索引。如果您的上定义...

    2017-03-20 回答

    二级索引??

    mysql中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(secondary indexes)。

    以innodb来说,每个innodb表具有一个特殊的索引称为聚集索引。如果您的表上定义有主键,该主键索引是聚集索引。如果你不定义为您的表的主键时,mysql取第一个唯一索引(unique)而且只含非空列(not null)作为主键,innodb使用它作为聚集索引。如果没有这样的列,innodb就自己产生一个这样的id值,它有六个字节,而且是隐藏的,使其作为聚簇索引。

    聚簇索引主要是为了方便存储。。所以二级索引应该都是对聚簇索引的索引。

    下面是mysql manual上的原话,也可能我理解有误。

    every innodb table has a special index called the clustered index where the data for the rows is stored. if you define a primary key on your table, the index of the primary key is the clustered index.

    if you do not define a primary key for your table, mysql picks the first unique index that has only not null columns as the primary key and innodb uses it as the clustered index. if there is no such index in the table, innodb internally generates a hidden clustered index on a synthetic column containing row id values. the rows are ordered by the id that innodb assigns to the rows in such a table. the row id is a 6-byte field that increases monotonically as new rows are inserted. thus, the rows ordered by the row id are physically in insertion order.

    accessing a row through the clustered index is fast because the row data is on the same page where the index search leads. if a table is large, the clustered index architecture often saves a disk i/o operation when compared to storage organizations that store row data using a different page from the index record. (for example, myisam uses one file for data rows and another for index records.)

    in innodb, the records in non-clustered indexes (also called secondary indexes) contain the primary key value for the row. innodb uses this primary key value to search for the row in the clustered index. if the primary key is long, the secondary indexes use more space, so it is advantageous to have a short primary key.

    展开全文
  • 个单列索引和联合索引的区别详解

    万次阅读 多人点赞 2018-06-24 17:40:58
    那么当查询条件为2个及以上时,我们是创建个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下。 一、联合索引测试 注:Mysql版本为 5.7.20 创建测试(记录...

    背景:
    为了提高数据库效率,建索引是家常便饭;那么当查询条件为2个及以上时,我们是创建多个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下。


    一、联合索引测试

    注:Mysql版本为 5.7.20

    创建测试表(表记录数为63188):

    CREATE TABLE `t_mobilesms_11` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `userId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '用户id,创建任务时的userid',
      `mobile` varchar(24) NOT NULL DEFAULT '' COMMENT '手机号码',
      `billMonth` varchar(32) DEFAULT NULL COMMENT '账单月',
      `time` varchar(32) DEFAULT NULL COMMENT '收/发短信时间',
      `peerNumber` varchar(64) NOT NULL COMMENT '对方号码',
      `location` varchar(64) DEFAULT NULL COMMENT '通信地(自己的)',
      `sendType` varchar(16) DEFAULT NULL COMMENT 'SEND-发送; RECEIVE-收取',
      `msgType` varchar(8) DEFAULT NULL COMMENT 'SMS-短信; MSS-彩信',
      `serviceName` varchar(256) DEFAULT NULL COMMENT '业务名称. e.g. 点对点(网内)',
      `fee` int(11) DEFAULT NULL COMMENT '通信费(单位分)',
      `createTime` datetime DEFAULT NULL COMMENT '创建时间',
      `lastModifyTime` datetime DEFAULT NULL COMMENT '最后修改时间',
      PRIMARY KEY (`id`),
      KEY `联合索引` (`userId`,`mobile`,`billMonth`)
    ) ENGINE=InnoDB AUTO_INCREMENT=71185 DEFAULT CHARSET=utf8 COMMENT='手机短信详情'
    

    我们为userId, mobile, billMonth三个字段添加上联合索引!

    我们选择 explain 查看执行计划来观察索引利用情况:


    1.查询条件为 userid

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222'
    

    这里写图片描述

    可以通过key看到,联合索引有效


    2.查询条件为 mobile

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972'
    

    这里写图片描述
    可以看到联合索引无效


    3.查询条件为 billMonth

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE billMonth='2018-04'
    

    这里写图片描述
    联合索引无效


    4.查询条件为 userid and mobile

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND mobile='13281899972'
    

    这里写图片描述
    联合索引有效


    5.查询条件为 mobile and userid

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE  mobile='13281899972' AND userid='2222' 
    

    这里写图片描述
    在4的基础上调换了查询条件的顺序,发现联合索引依旧有效


    6.查询条件为 userid or mobile

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' OR mobile='13281899972'
    

    这里写图片描述
    and 换成 or,发现联合所索引无效


    7.查询条件为 userid and billMonth

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND billMonth='2018-04'
    

    这里写图片描述
    这两个条件分别位于联合索引位置的第一和第三,测试联合索引依旧有效


    8.查询条件为 mobile and billMonth

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND billMonth='2018-04'
    

    这里写图片描述
    这两个条件分别位于联合索引位置的第二和第三,发现联合索引无效


    9.查询条件为 userid and mobile and billMonth

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE  userid='2222' AND mobile='13281899972' AND billMonth='2018-04'
    

    这里写图片描述
    所有条件一起查询,联合索引有效!(当然,这才是最正统的用法啊!)


    二、单列索引测试

    创建三个单列索引:
    这里写图片描述

    1.查询条件为 userid and mobile and billMonth

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE  userid='2222' AND mobile='13281899972' AND billMonth='2018-04'
    

    这里写图片描述
    我们发现三个单列索引只有 userid 有效(位置为查询条件第一个),其他两个都没有用上。

    那么为什么没有用上呢?按照我们的理解,三个字段都加索引了,无论怎么排列组合查询,应该都能利用到这三个索引才对!

    其实这里其实涉及到了mysql优化器的优化策略!当多条件联合查询时,优化器会评估用哪个条件的索引效率最高!它会选择最佳的索引去使用,也就是说,此处userid 、mobile 、billMonth这三个索引列都能用,只不过优化器判断使用userid这一个索引能最高效完成本次查询,故最终explain展示的key为userid。


    2.查询条件为 mobile and billMonth

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND billMonth='2018-04'
    

    这里写图片描述
    我们发现此处两个查询条件只有 mobile 生效(位置也为查询条件第一个)


    3.查询条件为 userid or mobile

    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE  userid='2222' OR mobile='13281899972' 
    

    这里写图片描述
    这次把 and 换成 or,发现两个查询条件都用上索引了!

    我们在网上可能常常看到有人说or会导致索引失效,其实这并不准确。而且我们首先需要判断用的是哪个数据库哪个版本,什么引擎?

    比如我用的是mysql5.7版本,innodb引擎,在这个环境下我们再去讨论索引的具体问题。

    关于or查询的真相是:
    所谓的索引失效指的是:假如or连接的俩个查询条件字段中有一个没有索引的话,引擎会放弃索引而产生全表扫描。我们从or的基本含义出发应该能理解并认可这种说法,没啥问题。

    此刻需要注意type类型为index_merge
    我查资料说mysql 5.0 版本之前 使用or只会用到一个索引(即使如上我给userid和mobile都建立的单列索引),但自从5.0版本开始引入了index_merge索引合并优化!也就是说,我们现在可以利用上多个索引去优化or查询了。

    index_merge作用:
    1、索引合并是把几个索引的范围扫描合并成一个索引。
    2、索引合并的时候,会对索引进行并集,交集或者先交集再并集操作,以便合并成一个索引。
    3、这些需要合并的索引只能是一个表的。不能对多表进行索引合并。

    index_merge应用场景:

    1.对OR语句求并集,如查询SELECT * FROM TB1 WHERE c1="xxx" OR c2=""xxx"时,如果c1和c2列上分别有索引,可以按照c1和c2条件进行查询,再将查询结果合并(union)操作,得到最终结果

    2.对AND语句求交集,如查询SELECT * FROM TB1 WHERE c1="xxx" AND c2=""xxx"时,如果c1和c2列上分别有索引,可以按照c1和c2条件进行查询,再将查询结果取交集(intersect)操作,得到最终结果

    3.对AND和OR组合语句求结果


    三、结论

    通俗理解:
    利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处

    所以说创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用仅对后面的任意列执行搜索时,复合索引则没有用处。


    重点:

    多个单列索引多条件查询时优化器会选择最优索引策略可能只用一个索引,也可能将多个索引全用上! 但多个单列索引底层会建立多个B+索引树,比较占用空间,也会浪费一定搜索效率,故如果只有多条件联合查询时最好建联合索引!


    最左前缀原则:

    顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上,
    注:如果第一个字段是范围查询需要单独建一个索引
    注:在创建联合索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。这样的话扩展性较好,比如 userid 经常需要作为查询条件,而 mobile 不常常用,则需要把 userid 放在联合索引的第一位置,即最左边


    同时存在联合索引和单列索引(字段有重复的),这个时候查询mysql会怎么用索引呢?

    这个涉及到mysql本身的查询优化器策略了,当一个表有多条索引可走时, Mysql 根据查询语句的成本来选择走哪条索引;


    有人说where查询是按照从左到右的顺序,所以筛选力度大的条件尽量放前面。网上百度过,很多都是这种说法,但是据我研究,mysql执行优化器会对其进行优化当不考虑索引时,where条件顺序对效率没有影响真正有影响的是是否用到了索引


    联合索引本质:

    当创建**(a,b,c)联合索引时,相当于创建了(a)单列索引**,(a,b)联合索引以及**(a,b,c)联合索引**
    想要索引生效的话,只能使用 a和a,b和a,b,c三种组合;当然,我们上面测试过,a,c组合也可以,但实际上只用到了a的索引,c并没有用到!
    注:这个可以结合上边的 通俗理解 来思考!


    其他知识点:

    1、需要加索引的字段,要在where条件中
    2、数据量少的字段不需要加索引;因为建索引有一定开销,如果数据量小则没必要建索引(速度反而慢)
    3、避免在where子句中使用or来连接条件,因为如果俩个字段中有一个没有索引的话,引擎会放弃索引而产生全表扫描
    4、联合索引比对每个列分别建索引更有优势,因为索引建立得越多就越占磁盘空间,在更新数据的时候速度会更慢。另外建立多列索引时,顺序也是需要注意的,应该将严格的索引放在前面,这样筛选的力度会更大,效率更高


    最后的说明:

    网上关于索引优化等文章太多了,针对各个数据库各个版本各种引擎都可能存在不一样的说法

    我们的SQL引擎自带的优化也越来越强大,说不定你的某个SQL优化认知,其SQL引擎在某次升级中早就自优化了。

    所以要么跟进官方文档,要么关注数据库大牛的最新文章,要么在现有数据库环境下自己去亲手测试!

    数据库领域的水很深。。大家加油。。共勉 ~

    展开全文
  • 一、介绍联合索引:对个字段同时建立索引(联合索引是有顺序的,比如ABC,ACB是完全不同的两种联合索引)。覆盖索引:即从辅助索引中得到查询的记录,而不需要查询聚集索引中的记录,覆盖索引必须要存储索引列的值,...

    d70b0d19269b9c3e9125da0f6136821a.png

    一、介绍联合索引:对多个字段同时建立索引(联合索引是有顺序的,比如ABC,ACB是完全不同的两种联合索引)。覆盖索引:即从辅助索引中得到查询的记录,而不需要查询聚集索引中的记录,覆盖索引必须要存储索引列的值,而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree索引做覆盖索引。索引条件下推:称为Index Condition Pushdown (ICP),这是MySQL提供的用某一个索引对一个特定的表来获取元组”,注意我们这里特意强调了“一个”,这是因为这样的索引优化不是用于多表连接而是用于单表扫描,确切地说,是单表利用索引进行扫描以获取数据的一种方式。回表查询:先定位主键值,再定位行记录,它的性能较扫一遍索引树更低。二、区别:1、联合索引根据创建联合索引的顺序,以最左原则进行where检索,比如(age,name)以age=1 或 age= 1 and name=‘陈五’可以使用索引,单以name='陈五' 不会使用索引,考虑到存储空间的问题,还请根据业务需求,将查找频繁的数据进行靠左创建索引。再如:   a、查出用户名的第一个字是“陈”开头的人的密码。即查询条件子句为"where name like '陈%'"
        b、查出用户名中含有“陈”字的人的密码。即查询条件子句为"where username like '%陈%'"
        c、查出用户名以“陈”字结尾的人的密码。即查询条件子句为"where username like '%陈'"    以上三种情况下,只有第1种能够使用(name, password)联合索引来加快查询速度。这就是最左前缀的第二层含义:索引可以用于查询条件字段为索引字段,根据字段值最左若干个字符进行的模糊查询。维护索引需要代价,所以有时候我们可以利用“最左前缀”原则减少索引数量,上面的(name,password)索引,也可用于根据name查询age的情况。当然,使用这个索引去查询age的时候是需要进行回表的,当这个需求(根据name查询age)也是高频请求时,我们可以创建(name,password,age)联合索引,这样,我们需要维护的索引数量不变。 创建索引时,我们也要考虑空间代价,使用较少的空间来创建索引假设我们现在不需要通过name查询password了,相反,经常需要通过name查询age或通过age查询name,这时候,删掉(name,password)索引后,我们需要创建新的索引,我们有两种选择1、(name,age)联合索引 + age字段索引2、(age,name)联合索引 + name单字段索引一般来说,name字段比age字段大的多,所以,我们应选择第一种,索引占用空间较小。
    2、覆盖索引:        如果查询条件使用的是普通索引(或是联合索引的最左原则字段),查询结果是联合索引的字段或是主键,不用回表操作,直接返回结果,减少IO磁盘读写读取正行数据。(使用explain,可以通过输出的extra列来判断,对于一个索引覆盖查询,显示为using index, MySQL查询优化器在执行查询前会决定是否有 索引覆盖 查询)介绍有点笼统,下面举个例子说明下,
    执行语句(A) select password from table where name = '陈五';
    当sql语句的所求查询字段(select列)和查询条件字段(where子句)全都包含在一个索引中,可以直接使用索引查询而不需要回表。这就是覆盖索引,通过使用覆盖索引,可以减少搜索树的次数,是常用的性能优化手段。
    例如上面的语句(A)是一个高频查询的语句,我们可以建立(name,password)的联合索引,这样,查询的时候就不需要再去回表操作了,可以提高查询效率。当然,添加索引是有维护代价的,所以添加时也要权衡一下。
    (将被查询的字段,建立到联合索引里去)

    3、索引条件下推:

    "select * from table where name like '陈%' and age > 10".like '%’ and age >10 检索,MySQL5.6版本之前,会对匹配的数据进行回表查询。5.6版本后,会先过滤掉age<10的数据,再进行回表查询,减少回表率,提升检索速度。a.    根据(name, age)联合索引查询所有满足名称以“”开头的索引,然后回表查询出相应的全行数据,然后再筛选出满足年龄小于等于10的用户数据。b.    根据(name,age)联合索引查询所有满足名称以“”开头的索引,然后直接再筛选出年龄小于等于10的索引,之后再回表查询全行数据。明显的,第二种方式需要回表查询的全行数据比较少,这就是mysql的索引下推。mysql默认启用索引下推,我们也可以通过修改系统变量optimizer_switch的index_condition_pushdown标志来控制
    SET optimizer_switch = 'index_condition_pushdown=off';

    4、回表:

    1)先扫描name索引树,找到主键值id=x。2)再扫描主键索引,找到对应行。这就是“回表查询”,先定位主键值,再通过主键值定位行记录,性能上较之直接查询索引树定位行记录更慢。通过 explain 分析sql
    explain select id, name from table where name = '陈五'
    查询返回 extra 为 Using index, 则走索引
    explain select id, name, sex from user where name = '陈五'
    查询返回 extra 为 NULL,意味着本次查询进行了“回表”操作,我们知道innodb采用B+树聚集索引,主键和数据绑定在一起,主键索引b+树的叶子节点存储了数据信息,而普通索引叶子节点存储的是主键值。因此,我们可以得知当通过普通索引查询时无法直接定位行记录,通常情况下,需要扫描两遍索引树。
    展开全文
  • mysql索引 个单列索引和联合索引的区别详解 背景: 为了提高数据库效率,建索引是家常便饭;那么当查询条件为2个及以上时,我们是创建个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢...
    mysql索引 多个单列索引和联合索引的区别详解
    
    背景:
    为了提高数据库效率,建索引是家常便饭;那么当查询条件为2个及以上时,我们是创建多个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下。
    
    一、联合索引测试
    注:Mysql版本为 5.7.20
    
    创建测试表(表记录数为63188):
    
    CREATE TABLE `t_mobilesms_11` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `userId` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '用户id,创建任务时的userid',
    `mobile` varchar(24) NOT NULL DEFAULT '' COMMENT '手机号码',
    `billMonth` varchar(32) DEFAULT NULL COMMENT '账单月',
    `time` varchar(32) DEFAULT NULL COMMENT '收/发短信时间',
    `peerNumber` varchar(64) NOT NULL COMMENT '对方号码',
    `location` varchar(64) DEFAULT NULL COMMENT '通信地(自己的)',
    `sendType` varchar(16) DEFAULT NULL COMMENT 'SEND-发送; RECEIVE-收取',
    `msgType` varchar(8) DEFAULT NULL COMMENT 'SMS-短信; MSS-彩信',
    `serviceName` varchar(256) DEFAULT NULL COMMENT '业务名称. e.g. 点对点(网内)',
    `fee` int(11) DEFAULT NULL COMMENT '通信费(单位分)',
    `createTime` datetime DEFAULT NULL COMMENT '创建时间',
    `lastModifyTime` datetime DEFAULT NULL COMMENT '最后修改时间',
    PRIMARY KEY (`id`),
    KEY `联合索引` (`userId`,`mobile`,`billMonth`)
    ) ENGINE=InnoDB AUTO_INCREMENT=71185 DEFAULT CHARSET=utf8 COMMENT='手机短信详情'
    
    
    我们为userId, mobile, billMonth三个字段添加上联合索引!
    
    我们选择 explain 查看执行计划来观察索引利用情况:
    
    1.查询条件为 userid
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222'
    
    
    
    可以通过key看到,联合索引有效
    
    2.查询条件为 mobile
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972'
    
    
    可以看到联合索引无效
    
    3.查询条件为 billMonth
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE billMonth='2018-04'
    
    
    联合索引无效
    
    4.查询条件为 userid and mobile
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND mobile='13281899972'
    
    
    联合索引有效
    
    5.查询条件为 mobile and userid
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND userid='2222'
    
    
    在4的基础上调换了查询条件的顺序,发现联合索引依旧有效
    
    6.查询条件为 userid or mobile
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' OR mobile='13281899972'
    
    
    把 and 换成 or,发现联合所索引无效!
    
    7.查询条件为 userid and billMonth
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND billMonth='2018-04'
    
    
    这两个条件分别位于联合索引位置的第一和第三,测试联合索引依旧有效!
    
    8.查询条件为 mobile and billMonth
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND billMonth='2018-04'
    
    
    这两个条件分别位于联合索引位置的第二和第三,发现联合索引无效!
    
    9.查询条件为 userid and mobile and billMonth
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND mobile='13281899972' AND billMonth='2018-04'
    
    
    所有条件一起查询,联合索引有效!(当然,这才是最正统的用法啊!)
    
    二、单列索引测试
    创建三个单列索引:
    
    
    1.查询条件为 userid and mobile and billMonth
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' AND mobile='13281899972' AND billMonth='2018-04'
    
    
    我们发现三个单列索引只有 userid 有效(位置为查询条件第一个),其他两个都没有用上
    
    2.查询条件为 mobile and billMonth
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE mobile='13281899972' AND billMonth='2018-04'
    
    
    我们发现此处两个查询条件只有 mobile 有效(位置也为查询条件第一个),后面的无效
    
    3.查询条件为 userid or mobile
    
    EXPLAIN SELECT * FROM `t_mobilesms_11` WHERE userid='2222' OR mobile='13281899972'
    
    
    这次把 and 换成 or,发现两个查询条件都用上索引了!
    
    三、结论
    通俗理解:
    利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。
    
    所以说创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用;仅对后面的任意列执行搜索时,复合索引则没有用处。
    
    重点:
    
    多个单列索引在多条件查询时只会生效第一个索引!所以多条件联合查询时最好建联合索引!
    
    最左前缀原则:
    
    顾名思义是最左优先,以最左边的为起点任何连续的索引都能匹配上,
    注:如果第一个字段是范围查询需要单独建一个索引
    注:在创建联合索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。这样的话扩展性较好,比如 userid 经常需要作为查询条件,而 mobile 不常常用,则需要把 userid 放在联合索引的第一位置,即最左边
    
    同时存在联合索引和单列索引(字段有重复的),这个时候查询mysql会怎么用索引呢?
    
    这个涉及到mysql本身的查询优化器策略了,当一个表有多条索引可走时, Mysql 根据查询语句的成本来选择走哪条索引;
    
    有人说where查询是按照从左到右的顺序,所以筛选力度大的条件尽量放前面。网上百度过,很多都是这种说法,但是据我研究,mysql执行优化器会对其进行优化,当不考虑索引时,where条件顺序对效率没有影响,真正有影响的是是否用到了索引!
    
    联合索引本质:
    
    当创建(a,b,c)联合索引时,相当于创建了(a)单列索引,(a,b)联合索引以及(a,b,c)联合索引
    想要索引生效的话,只能使用 a和a,b和a,b,c三种组合;当然,我们上面测试过,a,c组合也可以,但实际上只用到了a的索引,c并没有用到!
    注:这个可以结合上边的 通俗理解 来思考!
    
    其他知识点:
    
    1、需要加索引的字段,要在where条件中
    2、数据量少的字段不需要加索引;因为建索引有一定开销,如果数据量小则没必要建索引(速度反而慢)
    3、如果where条件中是OR关系,加索引不起作用
    4、联合索引比对每个列分别建索引更有优势,因为索引建立得越多就越占磁盘空间,在更新数据的时候速度会更慢。另外建立多列索引时,顺序也是需要注意的,应该将严格的索引放在前面,这样筛选的力度会更大,效率更高。

     

    展开全文
  • 联合索引列索引)

    万次阅读 多人点赞 2018-08-07 15:37:09
    联合索引是指对表上的个列进行索引,联合索引也是一棵B+树,不同的是联合索引的键值数量不是1,而是大于等于2. 最左匹配原则 假定上图联合索引的为(a,b)。联合索引也是一棵B+树,不同的是B+树在对索引a排序...
  • 那么当查询条件为2个及以上时,我们是创建个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下。一、联合索引测试注:Mysql版本为 5.7.20创建测试(记录数为...
  • 联合索引

    2020-06-16 15:08:42
    联合索引(各种索引) 聚集索引和非聚集索引 数据库中B+树索引可以分为聚集索引和非聚集索引(辅助索引) 聚集索引 每张只有一个聚集索引,且是建立在主键上面的。...联合索引上的个列...
  • 作者:FrancisQ https://juejin.im/post/5db19103e51d452a300b14c9索引...InnoDB的索引结构在InnoDB中是通过一种路搜索树——B+树实现索引结构的。在B+树中是只有叶子结点会存储数据,而且所有叶子结点会形成一个...
  • 一、联合索引测试 注:Mysql版本为 5.7.20 创建测试t_mobilesms_11(记录数为6万条): 我们为userId,mobile,billMonth三个字段添加上联合索引! 然后使用explain查看执行计划来观察索引利用情况: 1.查询...
  • 那么当查询条件为2个及以上时,我们是创建个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下。 一、联合索引测试 注:Mysql版本为 5.7.20 创建测试(记录数...
  • 那么当查询条件为2个及以上时,我们是创建个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下。 一、联合索引测试注:Mysql版本为 5.7.20 创建测试(记录数为...
  • 例如:有以下需求:每个人每一天只有可能产生一条记录:处了程序约定之外,数据库本身也可以设定:例如:user中有userID,userName两个字段,如果不希望有2条一模一样的记录,需要给user添加个字段的联合唯一索引:alter...
  • 通俗的解释:在某一列上加索引以提升相关语句查询效率,联合索引就是在个列上加索引。联合索引唯一性问题执行以下语句新建test用于演示:CREATE TABLE `test` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`u...
  • 复合索引 /列索引 /联合索引 /组合索引,一个意思,不同叫法。 含有个列字段的索引 联合索引也是一棵B+树,不同的是联合索引的键值数量不是1,而是大于等于2. 例如: 创建数据库 CREATE TABLE `test` ('aaa'...
  • 我们在下一篇讨论索引列次序的问题,首先看一下列独立索引的情况,以下面的结构为例:CREATE TABLE test (c1 INT,c2 INT,c3 INT,KEY(c1),KEY(c2),KEY(c3),);使用这种索引策略通常是一些权威的建议(例如在WHERE...
  • 各位大侠好,最近碰到个...项目里有两个,字段完全相同,字段索引也一样,只是索引名称不同,现在想把两个Union all做成一个视图,只是用来查询,想问下如果对一个有索引的字段做查询的话,具体用那个索引呢?
  • 那么当查询条件为2个及以上时,我们是创建个单列索引还是创建一个联合索引好呢?他们之间的区别是什么?哪个效率高呢?我在这里详细测试分析下。一、联合索引测试注:Mysql版本为 5.7.20创建测试(记录数为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,220
精华内容 488
关键字:

多表联合索引