首页 > 数据库 >mysql 索引

mysql 索引

时间:2023-10-27 19:45:58浏览次数:40  
标签:name 查询 索引 mysql test where select

1. 索引介绍

索引就是一种数据结构,类似于书的目录。意味着以后再查数据应该先找目录再找数据,而不是用翻页的方式查询数据

索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。

primary key     unique key    index key

注意:上面三种key前两种除了有加速查询的效果之外还有额外的约束条件(primary key:非空且唯一,unique key:唯一),而index key没有任何约束功能只会帮你加速查询

本质都是:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。

索引的影响:
    1. 在表中有大量数据的前提下,创建索引速度会很慢(建表的时候,如果明显需要索引,就提前加上)

# 以后实际添加索引的时候,尽量在空表的时候添加,在创建表的时候就添加索引,此时添加索引是最快的
# 如果表中数据已经有了,还需要添加索引,也可以,只不过创建索引的速度会很慢,不建议这样做

    2. 在索引创建完毕后,对表的查询性能会大幅度提升,但是写的性能会降低

# 但是,写的性能影响不是很大,因为在实际中,写的频率很少,大部分操作都是查询
# 如何添加索引?到底给哪些字段加索引呢?
'''没有固定答案,具体给哪个字段加索引,要看你实际的查询条件'''
select * from user where name='' and password='';
# 索引的使用其实是需要大量的工作经验,才能正确的判断出
'''不要一创建表就加索引,在一张表中,最多最多不要超过15个索引,索引越多,性能就会下降'''
# 如何数据量比较小,不需要加索引,100w一下一般不用加,mysql针对于1000w一下的数据,性能不会下降太多.


mysql数据库的所有索引结构是 b+树
只有叶子结点存放真实数据,根和树枝节点存的仅仅是虚拟数据

查询次数由树的层级决定,层级越低次数越少

一个磁盘块儿的大小是一定的,那也就意味着能存的数据量是一定的。如何保证树的层级最低呢?一个磁盘块儿存放占用空间比较小的数据项


# 以后加索引的时候,尽量给字段中存的是数字的列加,我们使用主键查询速度很快
select * from user where name = ''
select * from user where id = ''  # 主键查询的更快一些

=================================================

聚集索引(primary key)

聚集索引其实指的就是表的主键,innodb引擎规定一张表中必须要有主键。先来回顾一下存储引擎。

myisam在建表的时候对应到硬盘有几个文件(三个)

innodb在建表的时候对应到硬盘有几个文件(两个) frm文件只存放表结构,不可能放索引,也就意味着innodb的索引跟数据都放在idb表数据文件中。

特点:叶子结点放的一条条完整的记录
=================================================


辅助索引(unique,index)

辅助索引:查询数据的时候不可能都是用id作为筛选条件,也可能会用name,password等字段信息,那么这个时候就无法利用到聚集索引的加速查询效果。就需要给其他字段建立索引,这些索引就叫辅助索引


特点:叶子结点存放的是辅助索引字段对应的那条记录的主键的值(比如:按照name字段创建索引,那么叶子节点存放的是:{name对应的值:name所在的那条记录的主键值})

select name from user where name='jack';

上述语句叫覆盖索引:只在辅助索引的叶子节点中就已经找到了所有我们想要的数据

select age from user where name='jack';

上述语句叫非覆盖索引,虽然查询的时候命中了索引字段name,但是要查的是age字段,所以还需要利用主键才去查找

 联合索引

比较简单的是单列索引(b+tree)。遇到多条件查询时,不可避免会使用到多列索引。联合索引又叫复合索引。

b+tree结构如下:

每一个磁盘块在mysql中是一个页,页大小是固定的,mysql innodb的默认的页大小是16k,每个索引会分配在页上的数量是由字段的大小决定。当字段值的长度越长,每一页上的数量就会越少,因此在一定数据量的情况下,索引的深度会越深,影响索引的查找效率。



对于复合索引(多列b+tree,使用多列值组合而成的b+tree索引)。遵循最左侧原则,从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a a,b a,b,c 3种组合进行查找,但不支持 b,c进行查找。当使用最左侧字段时,索引就十分有效。

创建表test如下:

create table test(

a int,

b int,

c int,

KEY a(a,b,c)

);

比如(a,b,c)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(a=? and b=? and c=?)这样的数据来检索的时候,b+树会优先比较a列来确定下一步的所搜方向,如果a列相同再依次比较b列和c列,最后得到检索的数据;但当(b=? and c=?)这样的没有a列的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候a列就是第一个比较因子,必须要先根据a列来搜索才能知道下一步去哪里查询。比如当(a=? and c=?)这样的数据来检索时,b+树可以用a列来指定搜索方向,但下一个字段b列的缺失,所以只能把a列的数据找到,然后再匹配c列的数据了, 这个是非常重要的性质,即索引的最左匹配特性。

以下通过例子分析索引的使用情况,以便于更好的理解联合索引的查询方式和使用范围。

一、多列索引在and查询中应用

select * from test where a=? and b=? and c=?;查询效率最高,索引全覆盖。

select * from test where a=? and b=?;索引覆盖a和b。

select * from test where b=? and a=?;经过mysql的查询分析器的优化,索引覆盖a和b。

select * from test where a=?;索引覆盖a。

select * from test where b=? and c=?;没有a列,不走索引,索引失效。

select * from test where c=?;没有a列,不走索引,索引失效。

二、多列索引在范围查询中应用

select * from test where a=? and b between ? and ? and c=?;索引覆盖a和b,因b列是范围查询,因此c列不能走索引。

select * from test where a between ? and ? and b=?;a列走索引,因a列是范围查询,因此b列是无法使用索引。

select * from test where a between ? and ? and b between ? and ? and c=?;a列走索引,因a列是范围查询,b列是范围查询也不能使用索引。

三、多列索引在排序中应用

select * from test where a=? and b=? order by c;a、b、c三列全覆盖索引,查询效率最高。

select * from test where a=? and b between ? and ? order by c;a、b列使用索引查找,因b列是范围查询,因此c列不能使用索引,会出现file sort。

四,总结

联合索引的使用在写where条件的顺序无关,mysql查询分析会进行优化而使用索引。但是减轻查询分析器的压力,最好和索引的从左到右的顺序一致。

使用等值查询,多列同时查询,索引会一直传递并生效。因此等值查询效率最好。

索引查找遵循最左侧原则。但是遇到范围查询列之后的列索引失效。

排序也能使用索引,合理使用索引排序,避免出现file sort。
————————————————

 

标签:name,查询,索引,mysql,test,where,select
From: https://www.cnblogs.com/lchengshao/p/17793026.html

相关文章

  • mysql
    mysql索引下推个人认为主要场景是组合索引上idx_age_rewardselect*fromt_userwhereage>20andreward=100000;联合索引当遇到范围查询(>、<)就会停止匹配,也就是 age字段能用到联合索引,但是reward字段则无法利用到索引。具体原因这里可以看这篇:索引常见面试......
  • Mysql 删除数据重重复
    一、背景二、实现查看表的重复数据条数SELECTcount(1)a,serial_noFROM`mud_weighbridge_record`GROUPBYserial_noHAVINGa>1;删除表的重复数据DELETEt1from mud_weighbridge_recordt1innerjoin(SELECTmin(record_id)record_id,serial_no,count(1)FROM......
  • MySQL学习(10)基于规则的优化
    前言MySQL为了更高的执行效率,会将客户端发送的SQL语句进行优化。条件化简MySQL优化器会对SQL语句中的表达式进行简化处理,以提高执行效率。移除不必要的括号。常量传递。a=5ANDb>a可优化为a=5ANDb>5。移除没用的条件。优化器会移除掉明显为TRUE或FALSE的表......
  • 数据库系列:前缀索引和索引长度的取舍
    数据库系列:MySQL慢查询分析和性能优化数据库系列:MySQL索引优化总结(综合版)数据库系列:高并发下的数据字段变更数据库系列:覆盖索引和规避回表数据库系列:数据库高可用及无损扩容数据库系列:使用高区分度索引列提升性能1背景有时候我们需要在字符类型的字段上建设索引,但是如果......
  • 借助Navicat实现将mysql表结构转表格
    借助Navicat实现将mysql表结构转表格SELECTCOLUMN_NAME列名,COLUMN_TYPE数据类型,DATA_TYPE字段类型,IF(IS_NULLABLE='NO','否','是')是否为空,COLUMN_DEFAULT默认值,COLUMN_COMMENT备注FROMINFORMATION_SCHEMA.COLUMNSWHEREt......
  • mysql 导入csv 文件
    1.获取mysql配置文件路径mysqld--verbose--help|grep.cnf2.mysqld文件添加配置[mysqld]...secure-file-priv="" 3.建表createtablet_table(bank_codetext,banktext);4.导入csv文件BankCode,Bank(表头提前移除)ACEH,ACEHAGRONIAGA,Bank......
  • mysql-日志管理
    一、mysql日志文件的作用1、能记录物理数据页面的修改的信息;2、能将数据从逻辑上恢复至事务之前的状态;3、能以二进制文件的形式记录了数据库中的操作;4、能记录错误的相关信息;5、能从主服务器中二进制文件取的事件等等。普通日志记录了服务器接收到的每一个查询或是命......
  • mysql-基于GTID的binlog日志
    一、什么是GTID从MySQL5.6.5开始新增了一种基于GTID的复制方式。通过GTID保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。在原来基于二进制日志的复制中,从库需要告知主库要从哪个偏移量pos值进行增量......
  • 解锁高效检索技能:掌握MySQL索引数据结构的精髓
    (文章目录)......
  • mysql5.7启用ssl连接(windows版本)
    环境:OS:windows2012Mysql:5.7.29 1.安装mysql安装步骤省略,mysql5.7默认安装都已经安装好了ssl的,并默认启用了的.证书在数据目录下 D:\mysql57\dataD:\mysql57\data>dir驱动器D中的卷是新加卷卷的序列号是7603-6C5BD:\mysql57\data>dir*.pem驱动器D中的......