第 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:
但是说明; 有时我们设计表的时候,可能会使用反3NF.,举例:
上面的相册表的设计就使用到了反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语句
细致的说明请参考优化.ppt
⑤解决问题: 我们发现目前这个语句没有使用到索引,因此我们先考虑使用索引解决.
创建普通索引: CREATE INDEX 索引名 ON 表名(列)
⑥看看此时速度怎样
3.7索引的工作原理
图:
3.8补充知识点
①当一个表的存储引擎是MyISAM 时,对应三个文件
表名.frm 【表的结构】
表名.myd 【表的数据】
表名.myi 【索引的数据】
点击观看本章节视频讲解: http://www.tudou.com/programs/view/GEmdvfAhGvU/
未完待续...