Mysql数据库性能优化二

 更新时间:2016年4月15日 09:01  点击:1711

在上篇文章给大家介绍了mysql数据库性能优化一,今天继续接着上篇文章给大家介绍数据库性能优化相关知识。具体内容如下所示:

建立适当的索引

说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行个正确的'create index',查询速度就可能提高百倍千倍,这可真有诱惑力。可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的I/O。

是不是建立一个索引就能解决所有的问题?ename上没有建立索引会怎样?

select * from emp where ename='研发部'; 

---测试案例命令如下 (最好以 select * from emp e,dept d where e.empno=123451 )

*添加主键

ALTER TABLE emp ADD PRIMARY KEY(empno); 

*删除主键

alter table emp drop primary key; 

索引的原理说明

没有索引为什么会慢?

使用索引为什么会快?

索引的代价

1、磁盘占用

2、对dml(update delete insert)语句的效率影响

btree 方式检索,算法复杂度: log2N 次数

 

哪些列上适合添加索引

1、较频繁的作为查询条件字段应该创建索引

select * from emp where empno = 1; 

2、唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件

select * from emp where sex = '男' 

3、更新非常频繁的字段不适合创建索引

select * from emp where logincount = 1 

4、不会出现在WHERE子句中的字段不该创建索引

索引的类型

•主键索引,主键自动的为主索引 (类型Primary)

•唯一索引 (UNIQUE)

•普通索引 (INDEX)

•全文索引 (FULLTEXT) [适用于MyISAM] ——》sphinx + 中文分词 coreseek [sphinx 的中文版 ]

•综合使用=>复合索引

简述mysql四种索引的区别

lPRIMARY 索引 =》在主键上自动创建

lUNIQUE 索引=> 只要是UNiQUE 就是Unique索引.(只能在字段内容不重复的情况下,才能创建唯一索引)

lINDEX 索引=>就是普通索引

lFULLTEXT => 只在MYISAM 存储引擎支持, 目的是全文索引,在内容系统中用的多, 在全英文网站用多(英文词独立). 中文数据不常用,意义不大,国内全文索引通常使用 sphinx来完成,全文索引只能在 char varchar text字段创建.

全文索引案例

1.创建表

create table news(id int , title varchar(32),con varchar(1024)) engine=MyISAM; 

2.建立全文索引

create fulltext index ful_inx on news (con); 

3.插入数据

这里要注意,对于常见的英文 fulltext 不会匹配,而且插入的语句本身是正确的.

'but it often happens that they are not above supporting themselves by dishonest means.which should be more disreputable.Cultivate poverty like a garden herb'

4.看看匹配度

mysql> select match(con) against('poverty') from news;
+-------------------------------+
| match(con) against('poverty') |
+-------------------------------+
| 0 |
| 0 |
| 0 |
| 0.9853024482727051 |
+------------------------------+ 

0表示没有匹配到,或者你的词是停止词,是不会建立索引的.

使用全文索引,不能使用like语句,这样就不会使用到全文索引了.

复合索引

create index 索引名 on 表名(列1,列2); 

索引的使用

建立索引

create [UNIQUE|FULLTEXT] index index_name on tbl_name (col_name [(length)] [ASC | DESC] , …..);
alter table table_name ADD INDEX [index_name] (index_col_name,...) 
添加主键(索引) ALTER TABLE 表名 ADD PRIMARY KEY(列名,..); 联合主键

删除索引

DROP INDEX index_name ON tbl_name;
alter table table_name drop index index_name; 
删除主键(索引)比较特别: alter table t_b drop primary key;

查询索引(均可)

show index(es) from table_name;
show keys from table_name;
desc table_Name; 

修改索引,我们一般是先删除在重新创建.

查询要使用索引最重要的条件是查询条件中需要使用索引。

下列几种情况下有可能使用到索引:

1,对于创建的多列索引,只要查询条件使用了最左边的列,索引一般就会被使用。

2,对于使用like的查询,查询如果是 '%aaa' 不会使用到索引, 'aaa%' 会使用到索引。

下列的表将不使用索引:

1,如果条件中有or,即使其中有条件带索引也不会使用。

2,对于多列索引,不是使用的第一部分,则不会使用索引。

3,like查询是以%开头

4,如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。(添加时,字符串必须'')

5,如果mysql估计使用全表扫描要比使用索引快,则不使用索引。

测试案例(就在前面的dept表上做演示.)

CREATE TABLE dept(
deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
dname VARCHAR(20) NOT NULL DEFAULT "",
loc VARCHAR(13) NOT NULL DEFAULT ""
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; 
--放入数据,前面应该已经添加了,如果没有则需要重新添加
--测试开始.

添加一个主键索引

alter table dept add primary key (deptno) 

--测试语句

explain select * from dept where deptno=1; 

结果是:

mysql> explain select * from dept where deptno=1;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: dept
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 3
ref: const
rows: 1
Extra:
1 row in set (0.00 sec) 

--创建多列索引

alter table dept add index myind (dname,loc); 

--证明对于创建的多列索引,只要查询条件使用了最左边的列,索引一般就会被使用

explain select * from dept where dname='研发部'; 会显示使用到了索引myind
explain select * from dept where loc='MsBDpMRX'; 不会显示使用到了索引myind

--对于使用like的查询

explain select * from dept where dname like '%研发部'; 不会显示使用到了索引myind
explain select * from dept where dname like '研发部%'; 会显示使用到了索引myind

--如果条件中有or,即使其中有条件带索引也不会使用

--为了演示,我们把复合索引删除,然后只在dname上加入索引.

alter table dept drop index myind
alter table dept add index myind (dname)
explain select * from dept where dname='研发部' or loc='aa';-- 就不会使用到dname列上的 

--如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引

select * from dept from dname=1234; //不会使用到索引
select * from dept from dname='1234'; //会使用到索引

查看索引的使用情况

show status like 'Handler_read%';

大家可以注意:

handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。

handler_read_rnd_next:这个值越高,说明查询低效。

* 这时我们会看到handler_read_rnd_next值很高,为什么,这是因为我们前面没有加索引的时候,做过多次查询的原因.

常用SQL优化

大批量插入数据(MySql管理员) 了解

对于MyISAM:

alter table table_name disable keys;
loading data//insert语句;
alter table table_name enable keys; 

对于Innodb:

1,将要导入的数据按照主键排序

2,set unique_checks=0,关闭唯一性校验。

3,set autocommit=0,关闭自动提交。

优化group by 语句

默认情况,MySQL对所有的group by col1,col2进行排序。这与在查询中指定order by col1, col2类似。如果查询中包括group by但用户想要避免排序结果的消耗,则可以使用order by

null禁止排序

有些情况下,可以使用连接来替代子查询。

因为使用join,MySQL不需要在内存中创建临时表。(讲解)

如果想要在含有or的查询语句中利用索引,则or之间的每个条件列都必须用到索引,如果没有索引,则应该考虑增加索引(与环境相关 讲解)

select * from 表名 where 条件1='' or 条件2='tt'
explaine select * from dept group by dname; =>这时显示 extra: using filesort 说明会进行排序
explaine select * from dept group by dname order by null =>这时不含有显示 extra: using filesort 说明不会进行排序

***有些情况下,可以使用连接来替代子查询。因为使用join,MySQL不需要在内存中创建临时表

explain select * from emp , dept where emp.deptno=dept.deptno;

和下面比较就可以说明问题!!

explain select * from emp left join dept on emp.deptno=dept.deptno;

选择合适的存储引擎

MyISAM:默认的MySQL存储引擎。如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性要求不是很高。其优势是访问的速度快。

InnoDB:提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比MyISAM,写的处理效率差一些并且会占用更多的磁盘空间。

Memory:数据存在内存中,服务重启时,数据丢失

MyISAM: 在插入数据时,默认放在最后. ,删除数据后,空间不回收.(不支持事务和外键)

InnoDB 支持事务和外键

对应我们程序员说,常用的存储引擎主要是 myisam / innodb / memory,heap 表

如果选用小原则:

1.如果追求速度,不在乎数据是否一直把保存,也不考虑事务,请选择 memory 比如存放用户在线状态.

2.如果表的数据要持久保存,应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性要求不是很高。选用MyISAM

3.如果需要数据持久保存,并提供了具有提交、回滚和崩溃恢复能力的事务安全,请选用Innodb

选择合适的数据类型

在精度要求高的应用中,建议使用定点数来存储数值,以保证结果的准确性。deciaml 不要用float

对于存储引擎是MyISAM的数据库,如果经常做删除和修改记录的操作,要定时执行optimize table table_name;功能对表进行碎片整理。

日期类型要根据实际需要选择能够满足应用的最小存储的早期类型

create table bbs(id int ,con varchar(1024) , pub_time int);
date('Ymd',时间-3*24*60*60); 2038年-1-19

对于使用浮点数和定点数的案例说明

create table temp1( t1 float(10,2), t2 decimal(10,2));
insert into temp1 values(1000000.32,1000000,32); 发现 t1 成了 1000000.31 所以有问题.

对于optimize table 表名 演示

create table temp2( id int) engine=MyISAM;
insert into temp2 values(1); insert into temp2 values(2); insert into temp2 values(3);
insert into temp2 select * from temp2;--复制
delete from temp2 where id=1; 发现 该表对于的数据文件没有变小

定期执行 optimize table temp2 发现表大小变化,碎片整理完毕

&&对于InnoDB它的数据会存在data/ibdata1目录下,在data/数据库/只有一个 *.frm表结构文件.

关于mysql数据库性能优化二小编就给大家介绍到这里,希望对大家有所帮助!

[!--infotagslink--]

相关文章

  • MySQL性能监控软件Nagios的安装及配置教程

    这篇文章主要介绍了MySQL性能监控软件Nagios的安装及配置教程,这里以CentOS操作系统为环境进行演示,需要的朋友可以参考下...2015-12-14
  • 详解Mysql中的JSON系列操作函数

    新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
  • 深入研究mysql中的varchar和limit(容易被忽略的知识)

    为什么标题要起这个名字呢?commen sence指的是那些大家都应该知道的事情,但往往大家又会会略这些东西,或者对这些东西一知半解,今天我总结下自己在mysql中遇到的一些commen sense类型的问题。 ...2015-03-15
  • MySQL 字符串拆分操作(含分隔符的字符串截取)

    这篇文章主要介绍了MySQL 字符串拆分操作(含分隔符的字符串截取),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
  • mysql的3种分表方案

    一、先说一下为什么要分表:当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。根据个人经验,mysql执行一个sql的过程如下:1...2014-05-31
  • Windows服务器MySQL中文乱码的解决方法

    我们自己鼓捣mysql时,总免不了会遇到这个问题:插入中文字符出现乱码,虽然这是运维先给配好的环境,但是在自己机子上玩的时候咧,总得知道个一二吧,不然以后如何优雅的吹牛B。...2015-03-15
  • Centos5.5中安装Mysql5.5过程分享

    这几天在centos下装mysql,这里记录一下安装的过程,方便以后查阅Mysql5.5.37安装需要cmake,5.6版本开始都需要cmake来编译,5.5以后的版本应该也要装这个。安装cmake复制代码 代码如下: [root@local ~]# wget http://www.cm...2015-03-15
  • 用VirtualBox构建MySQL测试环境

    宿主机使用网线的时候,客户机在Bridged Adapter模式下,使用Atheros AR8131 PCI-E Gigabit Ethernet Controller上网没问题。 宿主机使用无线的时候,客户机在Bridged Adapter模式下,使用可选项里唯一一个WIFI选项,Microsoft Virtual Wifi Miniport Adapter也无法上网,故弃之。...2013-09-19
  • 忘记MYSQL密码的6种常用解决方法总结

    首先要声明一点,大部分情况下,修改MySQL密码是需要有mysql里的root权限的...2013-09-11
  • MySQL数据库备份还原方法

    MySQL命令行导出数据库: 1,进入MySQL目录下的bin文件夹:cd MySQL中到bin文件夹的目录 如我输入的命令行:cd C:/Program Files/MySQL/MySQL Server 4.1/bin (或者直接将windows的环境变量path中添加该目录) ...2013-09-26
  • Mysql命令大全(详细篇)

    一、连接Mysql格式: mysql -h主机地址 -u用户名 -p用户密码1、连接到本机上的MYSQL。首先打开DOS窗口,然后进入目录mysql/bin,再键入命令mysql -u root -p,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密...2015-11-08
  • Navicat for MySQL 11注册码\激活码汇总

    Navicat for MySQL注册码用来激活 Navicat for MySQL 软件,只要拥有 Navicat 注册码就能激活相应的 Navicat 产品。这篇文章主要介绍了Navicat for MySQL 11注册码\激活码汇总,需要的朋友可以参考下...2020-11-23
  • mysql IS NULL使用索引案例讲解

    这篇文章主要介绍了mysql IS NULL使用索引案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-08-14
  • node.js如何操作MySQL数据库

    这篇文章主要介绍了node.js如何操作MySQL数据库,帮助大家更好的进行web开发,感兴趣的朋友可以了解下...2020-10-29
  • 基于PostgreSQL和mysql数据类型对比兼容

    这篇文章主要介绍了基于PostgreSQL和mysql数据类型对比兼容,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-25
  • RHEL6.5编译安装MySQL5.6.26教程

    一、准备编译环境,安装所需依赖包yum groupinstall 'Development' -y yum install openssl openssl-devel zlib zlib-devel -y yum install readline-devel pcre-devel ncurses-devel bison-devel cmake -y二、编译安...2015-10-21
  • Mysql中 show table status 获取表信息的方法

    这篇文章主要介绍了Mysql中 show table status 获取表信息的方法的相关资料,需要的朋友可以参考下...2016-03-12
  • 20分钟MySQL基础入门

    这篇文章主要为大家分享了20分钟MySQL基础入门教程,快速掌握MySQL基础知识,真正了解MySQL,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-12-02
  • mongodb与mysql命令详细对比

    传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关...2013-09-11
  • Delphi远程连接Mysql的实现方法

    这篇文章主要介绍了Delphi远程连接Mysql的实现方法,需要的朋友可以参考下...2020-06-30