前言html
数据库是java开发过程必不可少的数据存储工具,一般咱们分为关系型数据库和非关系型数据库,上一篇中已经简单的介绍了redis,这里说一说关系型数据库mysql。java
一、mysql引擎mysql
这里只说咱们常见的两种引擎,MyISAM和Innodb,其余相关的引擎有兴趣的能够自行了解。首先咱们简单的说说这两种引擎的区别。redis
1)MyISAM,不支持事务,支持全文索引、表锁,在磁盘上有三个与表名相同的文件,.FRM文件存储表结构,.MYD文件存储表数据,.MYI文件存储表索引,MyISAM不缓存数据,只缓存索引。算法
2)InnoDB,支持事务、外键、行锁和非锁定读,即默认状况下读不产生锁。InnoDB由一系列后台线程和一大块内存组成。默认状况下,后台线程有7个,4个IO线程,1个master thread,1个lock监控线程,1个error监控线程。sql
在实际开发中,因为事务和行级锁等机制的缘由,Innodb可能接触的更多一些。MyISAM更多用于查询,尤为是select * from tableName,能够直接获取到数值,不须要全表扫描。数据库
二、mysql结构编程
mysql的结构以下图所示,我的十分喜欢这张图,经过这张图还能够大体了解一条SQL语句的执行过程后端
select * from tableName where name like '_zhang' select * from tableName where name like '%zhang'
上述两个sql没法使用name列上的索引缓存
select * from tableName where name like 'zhang_' select * from tableName where name like 'zhang%'
上述两个sql可使用name列上的索引
还有一点须要注意的是,对于变化较少的字段不建议添加索引,如性别的列,一般的值是0和1或者true和false,此列添加索引不会有太大的速度提高。一个表的索引个数也不建议过多,增删改数据的同时还要维护索引,过多的索引会下降数据库的效率。
四、mysql优化
mysql的优化从三个方面入手,包括建立表时的优化,索引的建立以及sql的优化
1)建立表时的优化
a)为表添加主键ID,最好使用无符号的int类型,设置成自增(注意分表时id重复的状况)
b)针对字典表能够考虑使用ENUM类型代替字符串,若是插入的值不在ENUM规定值内,则自动使用''空字符串代替
c)尽可能使用NOT NULL,使用NULL须要额外的空间,并且NULL没法使用索引
d)使用PROCEDURE ANALYSE()函数取得建议,根据表中数据进行分析,因此须要数据库中有必定的数据作基础,如:
SELECT * FROM sys_user PROCEDURE ANALYSE();
越小的列越快,在考虑往后数据扩展的前提下,尽可能使用较小存储单元的类型,如字典表中数据较少时,主键能够放弃使用INT,用MEDIUMINT、SMALLINT来代替,甚至使用更小的TINYINT,若是不须要记录时间,可使用DATE代替DATETIME
e)使用固定长度的表,若是表中全部的列都是固定长度的,表会被认为是“static”的,会加快查询速度,若是列中包含varchar、text或blog之一,则表不是固定长度的。固定长度的表因为定长,能够根据偏移量计算下一条数据的位置,而变长的表只能经过寻找下一条数据的主键。固定长度的表的缺点就是会形成空间浪费,由于不管存储数据大小,都会分配定长的空间。注:mysql字段占用空间与类型有关,如int(11)和int(3)都占用四个字节的长度,区别是根据存储数据的长度自动补全零位的个数,存储1111时,因为长度是4,int(3)不须要补零,int(11)会自动补全7个0
f)表分割,表分割能够分为水平分割和垂直分割。水平分割就是创建结构相同可是表名不一样的表,将数据按照hash运算以后存储在对应的表中,如sys_user_1,sys_user_2等;垂直分割是将表中一些不经常使用的或者会常常更新致使查询缓存失效的列分割出来,如家庭住址,最后登陆时间等字段。注:被分割的字段不能常常被JOIN,不然会极大下降性能
g)数据库读写分离
2)索引的建立
索引的建立就是在适合的列上添加索引,从而达到加快查询速度的效果,上面已经说起,这里再也不累述。
3)SQL的优化
a)使用explain关键字解析sql语句,如:
EXPLAIN SELECT * FROM (SELECT user_sex,COUNT(*) AS counts FROM sys_user u GROUP BY u.user_sex) count_t WHERE count_t.counts > 1
结果以下所示:
一般咱们关注的是type这一列,这里不要求记住全部,只须要记住几个典型的,而且了解哪一个更优便可,如system、const、eq_ref、ref、range、index、all等。这里有一篇文章,你们能够参考了解一下:《mysql explain 的type解释》
b)在查询结果明确只有一条的状况下,且该列上没有索引,使用LIMIT 1能够在查询到数据以后直接返回,避免全表扫描;判断一条数据是否存在时,使用SELECT 1能够提升查询速度,SELECT 1 > SELECT any column > SELECT *
c)避免SELECT *,用什么数据取什么列,减小网络数据传输
d)尽可能少用having、in、not in、is null等关键字或判断,对于having,可使用子查询来代替;in和not in可使用exists和not exists代替,若是数据连续,也可使用between and代替。
五、Innodb文件结构
InnoDB表由共享表空间或独立表空间、日志文件组和表结构文件组成。可使用show variables like 'innodb_file_per_table'查看是否开启了独立表空间,结果为ON时表示开启独立表空间;OFF时表示使用共享共享表空间。
select * from tableName where id =1 lock in share mode
select * from tableName where id =1 for update
本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利。
原文连接:http://www.cnblogs.com/1ning/p/6705129.html