好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

mysql数据库优化技术(1)

对 mysql 优化是一个综合性的技术, 主要包括: a 、表的设计合理化(符合 3NF ); b 、添加适当的索引( index ) [ 四种 ] :普通索引、主键索引、唯一索引( unique )、全文索引; c 、分表技术(水平分割、垂直分割); d 、读写分离; e 、存储过程(

对 mysql 优化是一个综合性的技术, 主要包括:

a 、表的设计合理化(符合 3NF );

b 、添加适当的索引( index ) [ 四种 ] :普通索引、主键索引、唯一索引( unique )、全文索引;

c 、分表技术(水平分割、垂直分割);

d 、读写分离;

e 、存储过程(模块化编程,可以提高速度);

f 、对 mysql 配置优化:配置最大并发数( my.ini 文件: max_connections 最大并发数,一般网站应设置到 1000 左右,太大的话内存会受不了)、调整缓存大小;

g 、 mysql 服务器硬件的升级;

h 、定时去清除不需要的数据,定时进行碎片整理(尤其是 MyISAM 存储引擎)。


? 数据库三层结构: PHP 程序 →dbms( 数据库管理系统,我们平常说的数据库其实是这个 ) →数据库(就是文件)。

? PHP 程序发送 sql 语句, dbms 进行编译后,再执行,对从数据库中返回的数据进行缓存,所以第二次 sql 请求时速度会变快。但是使用 sql 语句去操作,编译会很耗时,我们可以事先把一些经常用的代码在数据库中进行编码形成二进制,再直接调用,这个过程就是存储过程。

? 符合 3NF( 范式 ) 的表:表的范式,首先符合 1NF ,才能满足 2NF ,进一步满足 3NF 。

? 1NF :即表的列具有原子性,不可再分解,即列的信息,不能再分解。只要数据库是关系型数据库( mysql 、 Oracle 、 db2 、 sql server 、 informix 、 sysbase ),就自动满足 1NF 。

? 2NF :表的记录是唯一的,满足 2NF ,通常我们通过设计一个主键来实现。(主键:一般来讲不含业务逻辑,一般是自增的。因为主键不含业务逻辑,数据较稳定)

? 3NF :即表中不要有冗余数据,就是说,表的信息如果能推导出来,就不应该单独的设计一个字段来存放。下图不符合 3NF :


? 反 3NF :(相册表的浏览次数是对应 photo 表的图片浏览次数之和,为了提升响应速度,在每次浏览图片增加图片浏览次数的同时,相册表也同时添加浏览次数。虽然相册的浏览次数可以通过 photo 表推导出来,但是如果图片太多,双表查询时速度就会慢,通过设计字段 views 就可以解决,所以必要的数据冗余也是允许的)


? SQL 语句优化 :如何从一个大型项目中快速定位执行速度慢的语句(定位慢查询)?

? 常用语句: show status : show status like ‘ uptime ’ 查看 MySQL 启用多长时间; show [session|global] status like ‘ com_select ’ show status like ‘ com_update ’ ( 默认参数是 session 会话,指取出当前窗口的执行, global 取出从 mysql 启动到现在的执行次数 ) 查看对应语句执行了多少次 ( 存储引擎的选择偏向于参考哪个操作执行的多 ) ; show status like ‘ connections ’ 查看试图连接 mysql 服务器的次数; show status like ‘ slow_queries ’ ( 显示慢查询次数 ) 、

? 慢查询 ( 默认情况, mysql 认为 10 秒是一个慢查询 ) 优化:定位慢查询(构建一个大表 -> 存储过程;修改 mysql 的慢查询:显示慢查询值 show variables like ‘ long_query_time ’ ,修改值 set long_query_time=1 )

? 把慢查询的 sql 语句记录到我们的一个日志中(默认下 mysql 不会记录慢查询,需要在 mysql 启动时指定记录慢查询才行)。如果启用了慢查询记录日志,默认把这个文件放在 my.ini 文件记录的位置,如: datadir=d:/wamp/bin/mysql/mysql5.6.12/data( 这个地址不要轻易去修改 )

? 数据库中可以有多个数据对象:表、存储过程、视图、函数、触发器

? dual 亚元表,即一个空表。 select rand_string(6) from dual;


优化问题:

? 通过 explain 语句可以分析, mysql 如何执行 sql 语句

? 建立适当索引:

? 1 、添加索引:

? 主键索引的添加:当一张表,把某个列设为主键的时候,该列就是主键索引。创建表后再添加索引: alter table 表名 add primary key ( 列名 ) 。建立索引是有开销的。不能为空,也不能重复。

? 为什么创建主键索引后速度会变快:没建立索引之前, dbms 是按照给定的条件(如 id=2) 一个一个的顺序去查找。而建立索引后,可以利用二叉树算法(或哈希算法),建立索引文件。二叉树 (BTREE) 的效率 log 2N

? 普通索引的添加:普通索引的创建时,先建表,再创建普通索引。 create table aaa.... , create index 索引名 on 表 ( 列 )

? 全文索引的添加:全文索引主要针对文本的检索, 全文索引只对 MyISAM 有效,目前只针对英文有效( sphinx ( coreseek )技术处理中文),对停用词不建索引 。

CREATE TABLE articles (

id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,

title VARCHAR(200),

body TEXT,

FULLTEXT (title,body)

)engine=myisam charset utf8;

? 使用全文索引:错误用法 select * from articles where body like ‘%mysql%’;( 不会使用全文索引 ) ;正确用法: select * from articles where match(title,body) against ( ‘mysql’)

? 唯一索引的添加:当表的某列被指定为 unique 约束时,这列就是一个唯一索引(也采用了二叉树的算法)。 唯一索引是不能重复的,但是可以为空( NULL 可以有多个, ’’ 空字符串只能有一个); 创建表后再添加唯一索引: create unique index 索引名 on 表名 ( 列名 )

? 复合索引:索引作用在多列上。 alter table 表名 add index 索引名 ( 列名 1 ,列名 2...)

? explain :了解 sql 语句的执行情况




? 2 、查询索引: desc 表名(该方法的缺点是不能够显示索引的名字)、 show index(es) from 表名 (\G) 、 show keys from 表名 (\G)

? D:\wamp\bin\mysql\mysql5.6.12\data\ 可以看到这个目录中,一个数据库有一个文件夹,使用 InnoDB 建立的表由三个文件构成:


使用 MyASIN 引擎建立的表一般只有 .frm 文件,而起数据反正上以及目录的。

.frm 表示表的结构、 .MYD 表示表的数据、 MYI 表示表的索引 . 建立索引后 .MYI 文件会 变大。

? 3 、删除索引 : alter table 表名 drop index 索引名;如果删除的是主键索引,还可以: alter table 表名 drop primary key;

? 4 、修改索引: 一般是先删除,再重新创建。

? 使用索引的注意事项:磁盘占用;对 dml(update delete insert) 语句的效率影响,变慢:因为在增删改的时候,索引文件会更新(如删除一个记录,对应二叉树也应该删除对应记录),即使这样使用索引利大于弊,大部分网站查询多于增删改。

? 哪些列上适合添加索引:肯定在 where 中经常使用;该字段的内容不是唯一的几个值( sex );字段内容不是频繁变化的。


? 使用索引时的注意事项:

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

alter table dept add index myind (dnam,loc)//dnam 是左边的列, loc 是右边的列。

? 2 、对于使用 like 的查询,查询如果是 ’%aaa’(%aaa% 、 _aaa) 不会使用到索引, ’aaa%’会使用到索引 ( 即,在 like 查询时,关键字的首个字符是确定的,不能使用 % 或 _ ,如果前面有变化,则考虑全文索引 )

? 3 、如果条件中有 or ,所有使用到的字段都要建立索引(复合索引右边的列也要),建议尽量避免使用 or

? 4 、如果列类型是字符串,那一定要在条件中将值使用单引号引用起来,否则不使用索引。(值如果是字符串,不使用单引号,直接报错,如果是数字,不使用单引号不会报错,因为会自动转为字符串,但是无法使用索引)

? 5 、 mysql 会估计全表扫描比使用索引还快,则不使用索引。

? 查看索引使用的情况: show status like ‘handler_read%’

? 把一张表的数据导入到另一张表中,建议先禁用索引,要不然在导入数据的同时也会建立索引(不是重点)

? group by 分组查询时,默认分组后,还会自动排序( filesort ),可能会降低速度。在 group by 后增加 order by null 防止排序。

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

简单连接查询: select * from dept,emp where dept.deptno=emp.deptno;

左外连接: select * from dept left join emp on dept.deptno=emp.deptno;

? 如何选择 MySQL 的存储引擎:

? myisam :如果表对事务要求不高,同时是以查询和添加为主的,我们考虑使用 myisam 。比如 bbs 中的发帖表、回复表。

? InnoDB :对事务要求高,保存的数据都是重要数据,建议使用 InnoDB 。比如订单表、账户表。

? Memory :比如我们数据变化频繁,不需要入库,同时又频繁的查询和修改,考虑使用。

myiasm 数据查添加比 InnoDB 快,因为 myisam 直接在表尾插入,而 InnoDB 要先对数据进行事务安全的校验,并进行一个适当的排序。


在 PHP 开发中,通常不设置外键,通常是在程序中保证数据的一致。

? 如果数据库存储引擎是 myisam ,一定要定时进行碎片整理(要不然删除的数据永远不会删除): optimize table tablename

查看更多关于mysql数据库优化技术(1)的详细内容...

  阅读:45次