韩顺平 Mysql数据库优化(一) 优化概述

第 1 章 Mysql优化概述

网站的瓶颈在web(web吞吐量),程序对mysql的操作. 我们前面讲的页面静态化技术和memcached技术目的减少对mysql访问,但是总是访问数据库,所以我们需要对数据库本身进行优化. PHP和Java开发中,主要从7个方面优化

数据库()本身设计要规范(至少要求满足3NF) 3范式

创建适当索引(主键索引,普通索引,唯一索引,全文索引 sphinx->coreseek,空间索引)

优化SQL语句->如何定位慢查询

使用分表技术[思路: ->], 水平分割, 垂直分割

创建适当存储过程,触发器,自定义函数,视图 (1,模块化编程,2提高数据库的访问速度)

优化my.ini 文件(调整mysql的各级缓存.)

升级mysql硬件和软件 , 操作系统64, mysql就使用 64


点击观看本章节视频讲解: http://www.tudou.com/programs/view/W5lTxFELv04/

未完待续...

第 2 章Mysql数据库()设计

我们的表要满足1NF 基础上,才可以谈满足2NF, 目前最高级6NF,PHP网站说,我们只要满足3NF

1.1数据库的分类

1.1.1关系型数据库

比如mysql, oracle, sql server ,postgresql,informix,DB2

1.1.2非关系型数据库

面向对象和集合数据库.

1.1.3介于关系型和非关系型数据库间

mongodb数据库面向文档


2.2 1NF

所谓1NF:属性()具有原子性,不可在分割, 还有就是把同一张表不可以有两个相同列.

2.3 2NF

所谓2NF: 说表的记录具有唯一性., 即不能出现完全相同的两条记录.一般说,通过设置主键即可.

注意;主键最好是非业务逻辑主键,使用自增长.

2.4 3NF

3NF要保证数据没有冗余.即如果数据可能通过显示或者隐式的推导出,就不要单独设计一列.



比如下图就是满足3NF:

134819327.png

但是说明; 有时我们设计表的时候,可能会使用反3NF.,举例:


134839834.png

上面的相册表的设计就使用到了反3NF,但是他提高了效率


点击观看本章节视频讲解: http://www.tudou.com/programs/view/0Kj4sBsR3eI/

第 3 章如何定位慢查询

使用 showstatus 可以参考到mysql的各个参数,我们需要掌握的是以下参数, 其它请参考手册.

3.1 com_xxx

比如 com_select com_update com_insert com_delete , 比如我们在选择表究竟时候用MyISAM 还是 InnoDB ,可以看看该网站是以读和写操作为主,则可以使用MyISAM.

这里注意当我们使用 showstatus 来查询参数时,默认是当前会话.

show session status like xxxx

如果你要查看从数据库启动到现在状态

show global status like xxx

3.2 Connections

show status like ‘connections’ 可以查看当前连接的数量.

3.3 UPtime

表示数据库启动时间

3.4 Slow_queries

show status like ‘slow_queries’

显示慢查询次数, 默认情况下mysql认为慢查询时间是10s


3.5构建一个海量表

我们使用两个方法,蠕虫复制,可以构建大表,但是测试效果不好.

使用存储过程来创建海量表


模拟一个雇员管理系统

#模拟一个雇员管理系统

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 ;




#创建表EMP雇员

CREATE TABLE emp

(empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*编号*/

ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/

job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/

mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上级编号*/

hiredate DATE NOT NULL,/*入职时间*/

sal DECIMAL(7,2) NOT NULL,/*薪水*/

comm DECIMAL(7,2) NOT NULL,/*红利*/

deptno MEDIUMINT UNSIGNED NOT NULLDEFAULT 0 /*部门编号*/

)ENGINE=MyISAM DEFAULT CHARSET=utf8 ;


CREATE TABLE salgrade

(

grade MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,

losal DECIMAL(17,2) NOT NULL,

hisal DECIMAL(17,2) NOT NULL

)ENGINE=MyISAM DEFAULT CHARSET=utf8;


#测试数据

INSERT INTO salgrade VALUES (1,700,1200);

INSERT INTO salgrade VALUES (2,1201,1400);

INSERT INTO salgrade VALUES (3,1401,2000);

INSERT INTO salgrade VALUES (4,2001,3000);

INSERT INTO salgrade VALUES (5,3001,9999);


delimiter $$


#创建一个函数,可以返回一个随机的字符串


create function rand_string(n INT)

returns varchar(255) #该函数会返回一个字符串

begin

#定义了一个变量 chars_str类型 varchar(100)

#默认给 chars_str 初始值 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'

declare chars_str varchar(100)default

'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';

declare return_str varchar(255)default '';

declare i int default 0;

while i < n do

set return_str=concat(return_str,substring(chars_str,floor(1+rand()*52),1));

set i = i + 1;

end while;

return return_str;

end $$


#这里我们又自定了一个函数,返回一个随机的部门号

create function rand_num( )

returns int(5)

begin

declare i int default 0;

set i = floor(10+rand()*500);

return i;

end $$


#随即添加雇员[光标] 400w,Mysql开发中,可以在存储过程中调用你自己

#编写的函数

create procedure insert_emp(in start int(10),in max_num int(10))

begin

declare i int default 0;

#set autocommit =0 autocommit设置成0

#autocommit = 0 含义: 不要自动提交

set autocommit = 0;

repeat

set i = i + 1;

insert into emp values ((start+i),rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());

until i = max_num

end repeat;

commit;

end $$


调用存储过程添加400w数据

call insert_emp(100001,4000000);


3.6如何把慢查询记录到日志文件中

步骤

在默认情况下,mysql是不会记录慢查询, 所以我们要使用另外一种方式启动mysql,指令: cmd>bin\mysqld.exe �C safe-mode �Cslow-query-log

这样就会在mysql data目录,生成一个日志文件,该文件可以把慢查询语句记录到文件.

为了测试我们修改默认的慢查询时间

show variables like ‘long_query_time’ 【查询当前慢查询时间】

set long_query_time=1

当执行一个时间超过1秒的sql语句,就会被记录下来.

# Query_time: 1.500000 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 4000000

use temp100;

SET timestamp=1371870578;

select * from emp whereempno=456784;

分析慢查询时如何导致explain 工具

基本语法: explain sql \G

可以来分析mysql是如何执行你的sql语句

191528741.png

细致的说明请参考优化.ppt

解决问题: 我们发现目前这个语句没有使用到索引,因此我们先考虑使用索引解决.

创建普通索引: CREATE INDEX 索引名 ON 表名()


看看此时速度怎样


3.7索引的工作原理

:

191552594.png


3.8补充知识点

当一个表的存储引擎是MyISAM 时,对应三个文件

表名.frm 【表的结构】

表名.myd 【表的数据】

表名.myi 【索引的数据】

点击观看本章节视频讲解: http://www.tudou.com/programs/view/GEmdvfAhGvU/

未完待续...




你可能感兴趣的:(mysql,优化,概述)