热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql不走索引的场景

mysql不走索引的场景:1.什么是索引索引是一种数据结构,会对添加索引的字段的值进行排序存放,提高查询效率;一张表中可以添加多个索引;innodb存储引擎默认使用的是b+tree

 

  1.什么是索引

     索引是一种数据结构,会对添加索引的字段的值进行排序存放,提高查询效率;一张表中可以添加多个索引;innodb存储引擎默认使用的是b+tree索引结构,也支持哈希、全文索引。   

  2.索引的优缺点

  

  2.1索引的优点

     ①提高数据库查询效率      ②减少锁等待和死锁的产生(行锁是基于索引创建的)      ③减少主从复制从库的延迟时间(sql thread回放sql时会应用索引)   

  2.2索引的缺点

     ①索引维护成本高(可通过insert buffer,change buffer提升DML语句效率)      ②占用更多的存储空间(磁盘和内存)      ③索引过多会造成优化器负担   

  3.b+tree数据结构

  

  3.1 b+tree数据结构概括:b+tree是平衡多叉树的数据结构,是基于页进行管理数据;

     技术图片   

  3.2b+tree高度:2 (一般为2-4层);

     影响索引树高度因素:      ?。索引长度      。记录数      索引树高度不同消耗时间不同:      如sata磁盘(ssd固态硬盘同样计算):300iops,0.0033 /io      ?2层:0.0033*2 单位是秒      3层:0.0033*3 单位是秒   

  3.3非叶子节点

     保存键值(添加索引的字段的值)和指针   

  3.4指针

     指针与数据页是一种映射的关系,通过指针就可以找到对应的数据页   

  3.5叶子节点

     用于保存数据,保存所有记录的值,并经过排序   

  3.6双向指针(双向链表)

     用于保存相邻页的指针,提升范围查询效率   

  4.b+tree管理

  

  4.1 b+tree插入操作:(页旋转操作)

     情况一:b+tree插入数据时,叶子节点没有满      直接插入到对应的数据页      ?情况二:b+tree插入数据时,叶子节点已满(产生页分裂 split)      先取出中间值,存放到上一层非叶子节点中;      情况三:b+tree插入数据时,叶子节点和上一层的非叶子节点都已满(产生两次页分裂操作)   

  4.2 b+tree删除操作

     当叶子节点小于填充因子50%,就会发生页合并操作   

  5.相辅相成的聚集索引和辅助索引

  

  5.1 b+tree索引:索引的本质就是b+tree在数据库中的实现

  

   5.2 索引的分类:从物理存储角度分类

     聚集索引和辅助索引   

  5.3 聚集索引的选择:

     ①优先选择显示创建的主键索引来作为聚集索引      ②如没有主键索引就会选择第一个创建的非空的唯一索引作为聚集索引      ③系统自动创建一个实例级rowid作为聚集索引(6字节)   

  5.4 聚集索引的特点:

     ①叶子节点存放的是整行数据      ②一张表只能有一个聚集索引,因为实际的数据页只能按一颗b+tree进行排序      ③聚集索引的顺序决定表数据行的物理顺序   

  5.5 聚集索引的优势:

     ①不用回表查询就可以直接找到数据,节省更多的查询时间      ②范围查询性能得到提升 where 4  5.6 辅助索引:内部也是b+tree      ①辅助索引存放的是键值和主键值      ②每张表中可以存放多个辅助索引   

  6.覆盖索引与回表查询

  

  6.1 回表查询

     指回到聚集索引构建的b+tree去搜索的过程,就称为回表;回表查询要多经历几次io,消耗时间更多,性能相对较差   

  6.2 覆盖索引

     在一个查询语句中,使用到的b+tree上面的数据就覆盖我要查询需求,称为覆盖索引;可以减少对b+tree的搜索次数(减少io的消耗,不用回表查询)   

  7.创建高性能的主键索引

  

  7.1 主键索引创建的原则

     ①使用自增列作为主键 id int/bigint auto_increment primary key;      ②主键与业务不相关,不受业务变化影响      ③主键尽量不要修改、删除   

  7.2 主键索引的特点

     ①值不能为空,也不能重复      ②一张表只能有一个主键      ③创建辅助索引时,会隐式的将主键值保存,(name,pk)5.7自动识别里面的主键      ?where name=? and pk=?      where name=? order by pk   

  7.3 为什么建议使用自增列作为主键

     ①读;显示创建的主键会被作为聚集索引,在数据页上存整行数据,无论读记录任何的列,我们都不用回表查询,直接在主键构建的b+tree就可以找到。      ②写;写性能非常高,顺序获取页;离散获取页;insert buffer , change buffer      ③节省更多的内存   

  8.唯一索引与普通索引的性能差距

  

  8.1 唯一索引特点:

     - ?值不能重复,可以为空      ?- 一张表可以创建多个唯一索引      ?- 如果表中已有数据,添加唯一索引时,该字段的值,不能重复,如果有重复的,就会报错      select count(b) from t;      ?select count(distinct b) from t;   

  8.2 普通索引特点

     - ?值可以重复,可以为空      - 一张表可以创建多个普通索引   

  8.3 唯一索引与普通索引的性能差距

     - 读性能差距:      唯一索引:由于唯一性约束,查找到第一个满足条件的记录后,就会停止继续匹配      ?普通索引:值不是唯一,可能会有重复值,需要继续查找      总结:在读性能上,唯一索引的性能高于普通索引,性能差距非常小      -   写性能差距:      唯一索引:在进行写操作时要判断这个操作是否违反了唯一性约束。这个判断必须是在将页加载到内存后,才能进行判断,无法使用change buffer      ?普通索引:在进行写操作时,如果数据页不在内存中,会将写操作放到change buffer      总结:普通索引的写性能高于唯一索引   

  9.前缀索引带来的性能影响

  

  9.1 前缀索引作用:

     - 索引长度影响b+tree高度,索引长度越短越好      ?- 节省磁盘空和内存空间      - 建前缀索引时,如果合理的定义前缀索引的长度,会对查询性能带来好的影响   

  9.2 前缀索引长度创建不合理会带来哪些不好的影响?

     ?- 不合理的长度,会带来更多回表查询      总结:建前缀索引时,最重要的就是指定合理的长度   

  9.3 合理长度判断:

     select count(distinct a) from t;去除重复的值,总共有多少条记录      select count(distinct left(a, 3)) from t;      80%-90%就是合理的   

  9.4 前缀索引缺点:

     - ?无法使用覆盖索引      - ?无法进行order by和group by,会产生额外排序和产生临时表   

  10.生产中索引的管理

  

  ①建表时创建索引

     ?主键索引      create table t1(id int auto_increment primary key);      create table t2(      id int auto_increment,      primary key(id)      );      唯一索引      create table t1(name varchar(10) not null unique);      create table t2(      name varchar(10) not null,      unique key i_name(name)      );      前缀索引      create table t1(      name varchar(10) not null,      key i_name(name(5))      );      联合索引      create table t2(      name varchar(10) not null,      o_date datetime,      key i_name_date(name,o_date)      );      ?普通索引      create table t1(      name varchar(10) not null,      key i_name(name)      );   

   ②建表后创建索引

     create table t1(      id int ,      name varchar(10) not null,      o_date datetime,      title varchar(30) not null      );      建表后创建索引      主键索引      ?alter table t1 add primary key(id);      ?唯一索引      alter table t1 add unique index i_name(name);      前缀索引      ?alter table t1 add index i_title(title(10));      联合索引      alter table t1 add index i_name_date(name, o_date);      普通索引      ?alter table t1 add index i_o_date(o_date);      删除索引:      alter table t1 drop index 索引名称      查看索引:      show create table t1;      show index from t1;   

  11.SQL语句无法使用索引的情况

  

  ①where条件:

     ? 列进行计算:      ? explain select * from orders where o_custkey=o_custkey+1;      ? 列使用函数:      ? explain select * from orders where o_custkey=ceil(o_custkey);      ? 列进行隐式转换:      ? explain select * from emp where ename=007;   

  ②联合索引:用到范围查询,只能用到部分索引

  

  ③联表查询:

     ? 关联条件字符集不同,不走索引      ? 关联条件的列类型不同,不走索引   

  ④其他情况:

     ? 。select * from emp;      ? 。查询结果集大于数据量的30%,不走索引      ? explain select * from emp where empno > 7000;      ? 。索引本身失效      ? 。like ‘%s‘      ? explain select * from emp where ename like ‘%s‘;      ? 。not in(111,9999) 普通索引,如果是主键索引,会被优化为范围查询,可以利用索引      ? explain select * from emp where empno not in(111, 9999);      ? 。!=      ? explain select * from emp where empno != 9999;

mysql 不走索引的场景


推荐阅读
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • HashMap的扩容知识详解
    本文详细介绍了HashMap的扩容知识,包括扩容的概述、扩容条件以及1.7版本中的扩容方法。通过学习本文,读者可以全面了解HashMap的扩容机制,提升对HashMap的理解和应用能力。 ... [详细]
author-avatar
wyzf88_987
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有