Mysql数据库的优化(本文摘自于网络,文章末端有原文链接)
对于一个以数据为中心的应用,数据库的好坏直接影响到程序的性能,因此数据库性能至关重要。一
般来说,要保证数据库的效率,要做好以下四个方面的工作:
① 数据库设计
② sql语句优化
③ 数据库参数配置
④ 恰当的硬件资源和操作系统
这个顺序也表现了这四个工作对性能影响的大小
1.
通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中,为了更好地应用三个范式,就必须通俗地理解三个范式(通俗地理解是够用的理解,并不是最科学最准确的理解):
第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;(只要是关系型数据库都满足1NF)
第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识(设置主键),即实体的惟一性;
第三范式:3NF是对字段冗余性的约束,即我们的字段信息可以通过关联的关系,派生即可.(通常我们通过外键来处理)
但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。
具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。
适当的逆范式:
想要既查询到图片的点击次数,也可以查询相册被点击的次数。单纯在photos表中设置一个hits属性确实是符合3范式的,但是在
查询相册被点击的次数时,需要查询所有albumid为1的相册,然后将点击的次数相加,每次这样的查询效率是相当低的。那么不如在
相册表中设置一个hits属性,虽然违反了第三范式冗余了,但是效率大大提高了。
错误的逆范式:
sql语句的优化
面试题 :sql语句有几类
ddl (数据定义语言) [create alter drop]
dml(数据操作语言)[insert delete upate ]
select
dtl(数据事务语句) [commit rollback savepoint]
dcl(数据控制语句) [grant revoke]
MySQL客户端连接成功后,通过使用show [session|global] status 命令可以提供服务器状态信息。
其中的session来表示当前的连接的统计结果,global来表示自数据库上次启动至今的统计结果。默认是session级别的。
下面的例子:
show status like ‘Com_%’;
其中Com_XXX表示XXX语句所执行的次数。
重点注意:Com_select,Com_insert,Com_update,Com_delete通过这几个参数,
可以容易地了解到当前数据库的应用是以插入更新为主还是以查询操作为主,以及各类的SQL大致的执行比例是多少。
还有几个常用的参数便于用户了解数据库的基本情况。
Connections:试图连接MySQL服务器的次数
Uptime:服务器工作的时间(单位秒)
Slow_queries:慢查询的次数 (默认是10)
这里我们优化的重点是在 慢查询. (在默认情况下是10 )
显示查看慢查询默认时间的情况:show variables like 'long_query_time';
为了测试,我们搞一个海量表(mysql存储过程)
目的,就是看看怎样处理,在海量表中,查询的速度很快!
首先我们先建一个海量测试表:
压力测试sql脚本,生成1800000条的海量数据:
现在将慢查询的时间改为0.2s,set long_query_time=0.2;
(这种设置只是本次连接有效,设置永久有效需要再配置文件my.ini)
执行查找:select * from emp where empno=123456; 花费0.281s
查询慢查询的次数:show status like 'Slow_queries';
可见慢查询的次数已经为1.
查找:show variables like '%quer%';
可以查看查找的相关设置信息,从中可以看见show_query_log慢查询日志记录已经开启,记录的信息如下。
现在我们优化:加索引(性价比高,不需要开辟新的内存)
索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行个正确的’create index’,
查询速度就可能提高百倍千倍,这可真有诱惑力。
可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的(因为要维护索引信息文件),这些写操作,增加了大量的I/O。
(四种索引)
在emp表的 empno建立索引.
alter table emp add primary key(empno);
建索引之前:
建索引之后:
可看见.MYI索引文件变得非常大。
再次查询:
耗时0s,可见速度提高飞速。
索引的原理:
为什么加了索引速度变快?
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。在没有索引的情况下,数据库会遍历全部数据后选择符合条件的;
而有了相应的索引之后,数据库会直接在索引中查找符合条件的选项。
索引的代价:
1.磁盘占用(生成索引文件)
2.对dml(update delete insert )语句的效率影响
虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
介绍一款非常重要工具 explain, 这个分析工具可以对 sql语句进行分析,可以预测你的sql执行的效率.
他的基本用法是:
explain sql语句\G (\G可以使得显示呈列,便于查看 )
//根据返回的信息,我们可知,该sql语句是否使用索引,从多少记录中取出(rows,正是因为建立索引只需要从一个记录中取出),可以看到排序的方式.
删除索引后:
在一列上建立索引后只会在查询这一列的时候提高速度,但是其他列查询的速度不变。
在什么列上添加索引比较合适?
① 在经常查询的列上加索引.
② 列的数据,内容就只有少数几个值,不太适合加索引.
③ 内容频繁变化,不合适加索引
下列几种情况下有可能使用到索引:
1,对于创建的多列索引,只要查询条件使用了最左边的列,索引一般就会被使用。
只对左边的列建立的索引:
2,对于使用like的查询,查询如果是 ‘%aaa’ 不会使用到索引
‘aaa%’ 会使用到索引。
下列的表将不使用索引:
1,如果条件中有or,即使其中有条件带索引也不会使用。
2,对于多列索引,不是使用的第一部分,则不会使用索引。
3,like查询是以%开头
4,如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。
5,如果mysql估计使用全表扫描要比使用索引快,则不使用索引。
如何检测你的索引是否有效
show status like 'Handler_read%';
结论: Handler_read_key 越大越少
Handler_read_rnd_next 越小越好
MyISAM 和 Innodb区别
- MyISAM 不支持外键, Innodb支持
- MyISAM 不支持事务, Innodb支持.
- 对数据信息的存储处理方式不同.(如果存储引擎是MyISAM的,则创建一张表,对于三个文件.frm .myd .myi, 如果是Innodb则只有一张文件 *.frm,数据存放到ibdata1)
- MyISAM:默认的MySQL存储引擎。如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高。其优势是访问的速度快。
- InnoDB:提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比MyISAM,写的处理效率差一些并且会占用更多的磁盘空间。
对于 MyISAM 数据库,删除数据信息,只删掉内容,但是不释放空间。需要定时对表进行碎片整理清理。
optimize table 表名
以下是MYISAM和Innodb在优化上的策略:
优化group by 语句
默认情况,MySQL对所有的group by col1,col2进行排序。
这与在查询中指定order by col1, col2类似。
如果查询中包括group by但用户想要避免排序结果的消耗,则可以使用order by null禁止排序
不再使用文件排序:
有些情况下,可以使用连接来替代子查询。
因为使用join,MySQL不需要在内存中创建临时表。
如果想要在含有or的查询语句中利用索引,则or之间的每个条件列都必须用到索引,如果没有索引,则应该考虑增加索引或者使用union all操作。
选择合适的数据类型:
在精度要求高的应用中,建议使用定点数(decimal)来存储数值,以保证结果的准确性
1000000.32 万
create table sal(t1 float(10,2));
可见存的结果不准确。用decimal存之后:
create table sal2(t1 decimal(10,2));
表的划分
对表水平划分:
如果一个表的记录数太多了,比如上千万条,而且需要经常检索,那么我们就有必要化整为零了。
如果我拆成100个表,那么每个表只有10万条记录。当然这 需要数据在逻辑上可以划分。
一个好的划分依据,有利于程序的简单实现,也可以充分利用水平分表的优势。比如系统界面上只提供按月查询的功能,那么把表按月 拆分成12个,每个查询只查询一个表就了。
如果非要按照地域来分,即使把表拆的再小,查询还是要联合所有表来查,还不如不拆了。所以一个好的拆分依据是 最重要的。(UNION)
对表进行垂直划分:
有些表记录数并不多,可能也就2、3万条,但是字段却很长,表占用空间很大,检索表时需要执行大量I/O,严重降低了性能。
这个时候需要把大的字段拆分到另一个表,并且该表与原表是一对一的关系。 (JOIN)
联合查询(union)和连接查询(join)恰好表达了这两种方式的用法。
数据库参数配置
最重要的参数就是内存,我们主要用的innodb引擎,所以下面两个参数调的很大
innodb_additional_mem_pool_size = 64M innodb_buffer_pool_size =1G
对于myisam,需要调整key_buffer_size 当然调整参数还是要看状态,用show status语句可以看到当前状态,以决定改调整哪些参数
读写分离技术
如果数据库压力很大,一台机器支撑不了,那么可以用mysql复制实现多台机器同步,将数据库的压力分散。
基本的原理是让主数据库处理事务性查询,而从数据库处理SELECT查询。数据库复制被用来把事务性查询导致的变更同步到集群中 的从数据库。
原文章来源地址:http://www.cnblogs.com/xiangkejin/p/6899779.html
Mysql数据库的优化(本文摘自于网络,文章末端有原文链接)的更多相关文章
- [转]MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验
本文转自:http://liangweilinux.blog.51cto.com/8340258/1728131 年,嘿,废话不多说,下面开启MySQL优化之旅! 我们究竟应该如何对MySQL数据库进 ...
- MYSQL数据库的优化
我们究竟应该如何对MySQL数据库进行优化?下面我就从MySQL对硬件的选择.MySQL的安装.my.cnf的优化.MySQL如何进行架构设计及数据切分等方面来说明这个问题. 服务器物理硬件的优化 在 ...
- MySQL数据库的优化(下)MySQL数据库的高可用架构方案
MySQL数据库的优化(下)MySQL数据库的高可用架构方案 2011-03-09 08:53 抚琴煮酒 51CTO 字号:T | T 在上一篇MySQL数据库的优化中,我们跟随笔者学习了单机MySQ ...
- MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验
原文地址:http://liangweilinux.blog.51cto.com/8340258/1728131 首先在此感谢下我的老师年一线实战经验,我当然不能和我的老师平起平坐,得到老师三分之一的 ...
- 浅谈MySQL 数据库性能优化
MySQL数据库是 IO 密集型的程序,和其他数据库一样,主要功能就是数据的持久化以及数据的管理工作.本文侧重通过优化MySQL 数据库缓存参数如查询缓存,表缓存,日志缓存,索引缓存,innodb缓存 ...
- MySQL数据库的优化(上)单机MySQL数据库的优化
MySQL数据库的优化(上)单机MySQL数据库的优化 2011-03-08 08:49 抚琴煮酒 51CTO 字号:T | T 公司网站访问量越来越大,导致MySQL的压力越来越大,让我们自然想到的 ...
- mysql数据库性能优化(包括SQL,表结构,索引,缓存)
优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...
- MySQL数据库性能优化的关键参数(转)
我们在进行数据库管理和开发中经常会遇到性能问题,这就涉及到MySQL的性能优化.通过在网络上查找资料和笔者自己的尝试,我认为以下系统参数是比较关键的: 关键参数一:back_log 要求 MySQL ...
- MySQL 数据库性能优化之索引优化
接着上一篇 MySQL 数据库性能优化之表结构,这是 MySQL数据库性能优化专题 系列的第三篇文章:MySQL 数据库性能优化之索引优化 大家都知道索引对于数据访问的性能有非常关键的作用,都知道索引 ...
随机推荐
- springboot之搭建第一个helloworld程序
1.下载基本框架 在网站:https://start.spring.io/ 全部默认,基本没有改动 选择依赖,当然也可以自己在pom.xml加,我们直接在这里选择. 只选择Spring Web Sta ...
- 使用ICEM绘制非结构网格时,如何提高网格质量?【转载】
作者:杨淑娟 链接:https://www.zhihu.com/question/20851390/answer/26152732 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
- aop 通知的执行顺序
private static final org.slf4j.Logger Logger = LoggerFactory.getLogger(LoggerAop.class); /** * 线程池 异 ...
- Linux下的crontab定时执行任务简要说明
在LINUX中,周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron].cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间.cron的配置文件称为“cr ...
- 有效管理进程的几个linux命令
一般来说,应用程序进程的生命周期有三种主要状态:启动.运行和停止.如果我们想成为称职的管理员,每个状态都可以而且应该得到认真的管理.这八个命令可用于管理进程的整个生命周期. 启动进程 启动进程的最简单 ...
- java中json的使用和解析
1.创建json对象 1.1 创建JSONObject对象 使用map初始化json @Test public void test1() { Map<String, Object> map ...
- 使用ffmpeg裁剪和合并视频
剪切视频 使用 -ss 和 -t 选项,从第0秒开始,向后截取31秒视频,并保存 ffmpeg -ss :: -i video.mp4 -vcodec copy -acodec copy -t :: ...
- JAVA 基础编程练习题18 【程序 18 乒乓球赛】
18 [程序 18 乒乓球赛] 题目:两个乒乓球队进行比赛,各出三人.甲队为 a,b,c 三人,乙队为 x,y,z 三人.已抽签决定比赛名单. 有人向队员打听比赛的名单.a 说他不和 x 比,c 说他 ...
- Python——使用Notepad++运行
安装 安装python,安装完后找到python.exe,记录绝对路径,我的是:E:\log\python-3.7.4\python.exe 设置 用Notepad++打开python脚本,按F5会弹 ...
- 使用Android Studio时你应该知道的一切配置和使用Genymotion模拟器运行程序
参考博客: 配置Android Studio: http://www.cnblogs.com/wi100sh/p/5653427.html Android Studio打包APK: http://bl ...