索引

无论是面试,还是实际工作中,对于一个Java程序员来说,数据库优化是避不开的一个技术点,关于数据库的优化,在性能达不到要求的情况下,我大致给出以下几个方向:

(1)优化表结构,对常用字段和非常用的字段分开存储

(2)优化SQL,合理使用索引

(3)做数据库读写分离,减少IO压力,由于数据库对记录做了持久化并存储在磁盘上,对磁盘的I/O又是非常消耗性能的操作,因此读、写都在一个库中会大大增加I/O的压力

(4)尝试使用缓存,不要让数据都走数据库

(5)对业务做垂直拆分

(6)对表做水平拆分,这一步比较麻烦,要注意主键生成规则以及请求路由规则

以上6个点是有优先级的,本文关注的是第二点的索引部分。正确合理地使用索引对于数据库性能提升是至关重要的,本文暂时不分析索引原理,只是从实战的角度,总结一下索引的使用技巧,理论结合实践,印象会更深一些。

当然,事前我已经建立了一张很简单的student表并向表中插入了10万条数据,SQL为:

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`s_id` int(11) NOT NULL AUTO_INCREMENT,
`s_name` varchar(100) DEFAULT NULL,
`s_age` int(11) DEFAULT NULL,
`s_phone` varchar(30) DEFAULT NULL,
PRIMARY KEY (`s_id`),
KEY `s_name` (`s_name`)
) ENGINE=InnoDB, CHARSET=utf8;

使用普通索引与不使用普通索引的区别

先看一下不使用普通索引,进行查询,执行SQL语句:

select * from student where s_name = "99999ssss";

看一下查询时间:

花费了0.179秒,使用explain查看一下该条SQL语句的执行情况:

分析几个关键信息:

  • select_type:SIMPLE,这个不是很关键,只是表示这是一次简单的查询,没有join,没有union,没有中间表
  • type:ALL,表示该次SQL进行了全表查询
  • key:MySQL使用的索引名,这里null表示此次SQL查询MySQL并没有使用索引
  • rows:这个是最关键的,表示这次SQL查询了100665条记录

OK,接下来给s_name这一列加上普通索引:

alter table student add index s_name(s_name);

看一下运行结果:

看到在s_name上加上索引之后,查询速度马上快了3倍以上。

从分析结果上来看,由于此次SQL对列s_name使用了索引,因此rows只查了1条记录,大大提升了查询效率。

把索引建立在有大量重复数据的字段上

把索引建立在有大量重复数据的字段上,并不能有效地提升SQL效率,比如我的s_phone的取值为"00000000"~"99999999",此时对s_phone做查询,未加索引的时候:

看到这条select语句的查询时间是0.05秒,而给s_phone字段加了索引之后:

反而变为了0.064秒,并没有显著地提升查询效率,反而更加缓慢。通过explain语句,发现此次SQL通过索引查询了18000条rows,再去定位这18000多条数据,自然会慢一点。

这说明了,即使查询的时候用到了索引,也未必能提升查询的效率,索引建立在重复数据量很少的字段上效果才明显,但是这也将导致索引的增大,不过大多数时候这并不是太大的问题。

索引与like

不建议对索引列使用like语句,比如说执行以下两句SQL:

select * from student where s_name like "%99999ssss%";
select * from student where s_name like "%99999ssss";

看一下explain出来的结果,都是一样的:

发现没有用到索引,这是对索引列使用like的限制,要对索引列使用like,通配符只能在结尾,开头不可以有任何的通配符,比如:

select * from student where s_name like "99999ssss%";

此时再explain看一下:

看到这么实用like则使用到了索引,这不得不说是一个限制。

索引与函数

在索引列上使用MySQL函数也会导致索引失效,看一个例子:

select * from student where "99999ssss" = left(s_name, 9);

这条SQL语句非常好理解,查询s_name列中从左边开始截取9个字符后的字符串为"99999ssss"的记录,查看一下explain的结果:

结果很明显,没有用到索引,这表明对索引列使用函数将导致索引失效。

一个技巧是,依然使用=,但是索引列不使用函数而对常数项使用函数,这样索引就有效了,当然这条语句是无法这么优化的。

MySQL9:索引实战的更多相关文章

  1. MySQL索引实战经验总结

    MySQL索引对数据检索的性能至关重要,盲目的增加索引不仅不能带来性能的提升,反而会消耗更多的额外资源,本篇总结了一些MySQL索引实战经验. 索引是用于快速查找记录的一种数据结构.索引就像是数据库中 ...

  2. (Oracle)索引实战(转载)

    人们在使用SQL时往往会陷入一个误区,即太关注于所得的结果是否正确,而忽略了不同的实现方法之间可能存在的性能差异,这种性能差异在大型的或是复杂的数据库环境中(如联机事务处理OLTP或决策支持系统DSS ...

  3. Mysql之B+树索引实战

    索引代价 空间上的代价 一个索引都对应一棵B+树,树中每一个节点都是一个数据页,一个页默认会占用16KB的存储空间,所以一个索引也是会占用磁盘空间的. 时间上的代价 索引是对数据的排序,那么当对表中的 ...

  4. MySQL9:索引实战 (转)

    构建50万条数据过程: DROP TABLE IF EXISTS `students`; CREATE TABLE `students` ( `s_id` ) NOT NULL AUTO_INCREM ...

  5. Mysql:索引实战

    MySQL主要提供2种方式的索引:B-Tree索引,Hash索引 B树索引具有范围查找和前缀查找的能力,对于有N节点的B树,检索一条记录的复杂度为O(LogN).相当于二分查找. 哈希索引只能做等于查 ...

  6. mysql-9索引

    mysql索引的建立对于mysql的高效运行是很重要的,索引可以大大提高mysql的检索速度. 索引分为单列索引和组合索引. 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索 ...

  7. Mongodb索引实战

    最近碰到这样的一个需求,一张酒店政策优惠表,我们要根据用户入住和离开的时间,计算一家酒店的最低价政策前10位,数据库表字段如下: 'hid':88, 酒店id 'date':20150530, 入住日 ...

  8. MySQL索引介绍和实战

    索引是什么 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构. 可以得到索引的本质:索引是数据结构,索引的目的是提高查询效率,可以类比英语新华字典,根据目录定位词 ...

  9. sqlserver索引小结

    1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书 ...

随机推荐

  1. jquery-confirm使用方法

    简要教程 jquery-confirm是一款功能强大的jQuery对话框和确认框插件.它提供多种内置的主题效果,可以实现ajax远程加载内容,提供动画效果和丰富的配置参数等.它的特点还有: 可以使用键 ...

  2. Hillstone防火墙sslvpn配置与使用

    1.山石的sslvpn称为Secure Connect VPN,即scvpn. 2.WEB界面登陆防火墙,“用户”,“AAA服务器”,新建用户: 3.定义源IP池 即用户通过sslvpn拨号成功后获取 ...

  3. UEFI Shell命令操作总结

    什么是UEFI ShellUEFI Shell是一种特殊对待UEFI_APPLICATION.提供用户和UEFI系统之间的一个接口.它有很强大的功能,但是正常启动计算机系统时,不会用到UEFI She ...

  4. Android 8.0+ 更新安装apk失败的问题

    最近做项目发现Android 8.0+ 更新安装apk时 出现安装失败的情况  总结原因是 缺少安装的权限 Android 8.0 (Android O)为了针对一些流氓软件引导用户安装其他无关应用. ...

  5. 好用的.NET控制台测试项目

    在工作和学习上,我们经常需要创建项目,引用些其他的库,测试下自己的想法是否正确,需要捕捉一下异常.调用一下异步方法.记录一下log等等,这样的项目都是需要花费时间,为了较少花费的时间,产生了一个这样的 ...

  6. c#跨线程访问的代码和窗体关闭退出死循环的代码

    一:一段跨线程访问,给页面内的控件赋值的代码找了半天没找到,还得找了以前写的程序. 在这记下来吧 .  这是其他程序内可以跨线程访问的代码 . if (gridControl1.InvokeRequi ...

  7. SQL 2008发布与订阅

    网的教程很多,大都是不能成功,只有这一篇是成功的! https://www.cnblogs.com/DBArtist/p/5803271.html

  8. 现代编译原理——第六章:中间树 IR Tree 含源码

    转自: http://www.cnblogs.com/BlackWalnut/p/4559717.html 这一章,就虎书而言,理论知识点是及其少的,就介绍了为什么要有一个中间表示树.看下面这张图就能 ...

  9. Charles抓https请求详细步骤

    1.电脑上安装好Charles 2.电脑上安装证书 (1)点击Help - SSL Proxying - Install Charlse Root Certificate (2)在电脑上找到证书.此时 ...

  10. 浅析b-树 b+树 以及Mysql的Innodb,Myisam引擎

    B-树性质 B-树可以看作是对2-3查找树的一种扩展,即他允许每个节点有M-1个子节点. 1根节点至少有两个子节点 2每个节点有M-1个key,并且以升序排列 3位于M-1和M key的子节点的值位于 ...