mysql千万级数据量根据索引优化查询速度
(一)索引的作用
索引通俗来讲就相当于书的目录,当我们根据条件查询的时候,没有索引,便需要全表扫描,数据量少还可以,一旦数据量超过百万甚至千万,一条查询sql执行往往需要几十秒甚至更多,5秒以上就已经让人难以忍受了。
提升查询速度的方向一是提升硬件(内存、cpu、硬盘),二是在软件上优化(加索引、优化sql;优化sql不在本文阐述范围之内)。
能在软件上解决的,就不在硬件上解决,毕竟硬件提升代码昂贵,性价比太低。代价小且行之有效的解决方法就是合理的加索引。
索引使用得当,能使查询速度提升上万倍,效果惊人。
(二)mysql的索引类型:
mysql的索引有5种:主键索引、普通索引、唯一索引、全文索引、聚合索引(多列索引)。
唯一索引和全文索引用的很少,我们主要关注主键索引、普通索引和聚合索引。
1)主键索引:主键索引是加在主键上的索引,设置主键(primary key)的时候,mysql会自动创建主键索引;
2)普通索引:创建在非主键列上的索引;
3)聚合索引:创建在多列上的索引。
(三)索引的语法:
查看某张表的索引:show index from 表名;
创建普通索引:alter table 表名 add index 索引名 (加索引的列)
创建聚合索引:alter table 表名 add index 索引名 (加索引的列1,加索引的列2)
删除某张表的索引:drop index 索引名 on 表名;
(四)性能测试
测试环境:博主工作用台式机
处理器为Intel Core i5-4460 3.2GHz;
内存8G;
64位windows。
1:创建一张测试表
- DROP TABLE IF EXISTS `test_user`;
- CREATE TABLE `test_user` (
- `id` bigint(20) PRIMARY key not null AUTO_INCREMENT,
- `username` varchar(11) DEFAULT NULL,
- `gender` varchar(2) DEFAULT NULL,
- `password` varchar(100) DEFAULT NULL
- ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
存储引擎使用MyISAM是因为此引擎没有事务,插入速度极快,方便我们快速插入千万条测试数据,等我们插完数据,再把存储类型修改为InnoDB。
2:使用存储过程插入1千万条数据
- create procedure myproc()
- begin
- declare num int;
- set num=1;
- while num <= 10000000 do
- insert into test_user(username,gender,password) values(num,'保密',PASSWORD(num));
- set num=num+1;
- end while;
- end
- call myproc();
由于使用的MyISAM引擎,插入1千万条数据,仅耗时246秒,若是InnoDB引擎,插入100万条数据就要花费数小时了。
然后将存储引擎修改回InnDB。使用如下命令: alter table test_user engine=InnoDB;此命令执行时间大约耗时5分钟,耐心等待。
tips:这里是测试,生产环境中不要随意修改存储引擎,还有alter table 操作,会锁整张表,慎用。其次:myisam引擎没有事务,且只是将数据写到内存中,然后定期将数据刷出到磁盘上,因此突然断电的情况下,会导致数据丢失。而InnDB引擎,是将数据写入日志中,然后定期刷出到磁盘上,所以不怕突然断电等情况。因此在实际生产中能用InnDB则用。
3:sql测试
select id,username,gender,password from test_user where id=999999
耗时:0.114s。
因为我们建表的时候,将id设成了主键,所以执行此sql的时候,走了主键索引,查询速度才会如此之快。
我们再执行select id,username,gender,password from test_user where username='9000000'
耗时:4.613s。
我们给username列加上普通索引。
ALTER TABLE `test_user` ADD INDEX index_name(username) ;
此过程大约耗时 54.028s,建索引的过程会全表扫描,逐条建索引,当然慢了。
再来执行:selectid,username,gender,password from test_user where username='9000000'
耗时:0.043s。
再用username和password来联合查询
select id,username,gender,password from test_user where username='9000000' or `password`='*3A70E147E88D99888804E4D472410EFD9CD890AE'
此时虽然我们队username加了索引,但是password列未加索引,索引执行password筛选的时候,还是会全表扫描,因此此时
查询速度立马降了下来。
耗时:4.492s。
当我们的sql有多个列的筛选条件的时候,就需要对查询的多个列都加索引组成聚合索引:
加上聚合索引:ALTER TABLE `test_user` ADD INDEX index_union_name_password(username,password)
再来执行:
耗时:0.001s。
开篇也说过软件层面的优化一是合理加索引;二是优化执行慢的sql。此二者相辅相成,缺一不可,如果加了索引,还是查询很慢,这时候就要考虑是sql的问题了,优化sql。
实际生产中的sql往往比较复杂,如果数据量过了百万,加了索引后效果还是不理想,使用集群。
Tips:
1:加了索引,依然全表扫描的可能情况有:
索引列为字符串,而没带引号;
索引列没出现在where条件后面;
索引列出现的位置没在前面。
2:关联查询不走索引的可能情况有:
关联的多张表的字符集不一样;
关联的字段的字符集不一样;
存储引擎不一样;
字段的长度不一样。
mysql千万级数据量根据索引优化查询速度的更多相关文章
- (转载)MYSQL千万级数据量的优化方法积累
转载自:http://blog.sina.com.cn/s/blog_85ead02a0101csci.html MYSQL千万级数据量的优化方法积累 1.分库分表 很明显,一个主表(也就是很重要的表 ...
- MySQL 千万 级数据量根据(索引)优化 查询 速度
一.索引的作用 索引通俗来讲就相当于书的目录,当我们根据条件查询的时候,没有索引,便需要全表扫描,数据量少还可以,一旦数据量超过百万甚至千万,一条查询sql执行往往需要几十秒甚至更多,5秒以上就已经让 ...
- mysql千万级数据量查询出所有重复的记录
查询重复的字段需要创建索引,多个条件则创建组合索引,各个条件的索引都存在则不必须创建组合索引 有些情况直接使用GROUP BY HAVING则能直接解决:但是有些情况下查询缓慢,则需要使用下面其他的方 ...
- MYSQL千万级数据量的优化方法积累
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 在SQLite中使用索引优化查询速度
在进行多个表联合查询的时候,使用索引可以显著的提高速度,刚才用SQLite做了一下测试. 建立三个表: create table t1 (id integer primary key,num inte ...
- MySQL千万级数据分区存储及查询优化
作为传统的关系型数据库,MySQL因其体积小.速度快.总体拥有成本低受到中小企业的热捧,但是对于大数据量(百万级以上)的操作显得有些力不从心,这里我结合之前开发的一个web系统来介绍一下MySQL数据 ...
- 完全用nosql轻松打造千万级数据量的微博系统(转)
原文:http://www.cnblogs.com/imxiu/p/3505213.html 其实微博是一个结构相对简单,但数据量却是很庞大的一种产品.标题所说的是千万级数据量 也并不是一千万条微博信 ...
- 完全用nosql轻松打造千万级数据量的微博系统
其实微博是一个结构相对简单,但数据量却是很庞大的一种产品.标题所说的是千万级数据量也并不是一千万条微博信息而已,而是千万级订阅关系之间发布.在看 我这篇文章之前,大多数人都看过sina的杨卫华大牛的微 ...
- MySQL的or/in/union与索引优化
转载自:MySQL的or/in/union与索引优化 https://blog.csdn.net/zhangweiwei2020/article/details/80005590 假设订单业务表结构为 ...
随机推荐
- Spring中的转换器:Converter
配置spring的配置文件: <bean id="conversionService" class="org.springframework.context.sup ...
- IIS支持http协议的:put、delete等方法
HTTP常见方法:DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH 以下是从网上搜索的方法:其实经过测试,只配置最后那个web.config就可以实现这个功能: ...
- java笔记--ASCII编码认知和转换
ASCII是基于拉丁字母的一套电脑编码系统,主要用于显示英语字符是当今最通用的单字节编码.包括128个字符. --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs. ...
- .net 的page的OnInit方法
/// <summary> /// 重写父类的方法,父类要执行的方法已经被覆盖 /// </summary> /// <param name="e"& ...
- Linux下的Mysql备份/恢复
数据库逻辑备份 逻辑备份:将数据库的数据以逻辑的SQL语句的方式导出 查看帮助 mysqldump --help 0.数据库开启状态 1.备份某个特定的库: mysqldump -uroot -pro ...
- 沉淀再出发:IoC和AOP的本质
沉淀再出发:IoC和AOP的本质 一.前言 关于IoC和AOP这两个概念,如果我们没有深入的理解可以说是根本就不理解Spring这个架构的,同样的由Spring演变出来的Spring Boot和Spr ...
- BZOJ 1270 雷涛的小猫 dp
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1270 题目大意: 雷涛的小猫雷涛同学非常的有爱心,在他的宿舍里,养着一只因为受伤被救助 ...
- Java对html标签的过滤和清洗
OWASP HTML Sanitizer 是一个简单快捷的java类库,主要用于放置XSS 优点如下: 1.使用简单.不需要繁琐的xml配置,只用在代码中少量的编码 2.由Mike Samuel(谷歌 ...
- 【[POI2010]ANT-Antisymmetry】
开始复习字符串了 第一步肯定得是\(hash\) 首先理性分析一波不可能出现长度为奇数的反回文串,对称轴位置取反之后肯定和原来不相等了 我们可以枚举所有回文串的对称中心,之后我们发现这个样子是具有单调 ...
- 使用Jwt为.Net Core SignalR保驾护航
前言 SignalR Demo搭建起来之后,是没有相应的认证和授权功能的.于是乎,参考官方文档实现了相应的逻辑. 简单认证 首先使用稍微简单的方式实现.添加如下代码: services.AddAuth ...