mysql数据库优化韩顺平_韩顺平 Mysql数据库优化(一) 优化概述
第 1 章Mysql優(yōu)化概述
網(wǎng)站的瓶頸在web層(web吞吐量),程序?qū)ysql的操作.我們前面講的頁(yè)面靜態(tài)化技術(shù)和memcached技術(shù)目的減少對(duì)mysql訪問(wèn),但是總是訪問(wèn)數(shù)據(jù)庫(kù),所以我們需要對(duì)數(shù)據(jù)庫(kù)本身進(jìn)行優(yōu)化.在PHP和Java開發(fā)中,主要從7個(gè)方面優(yōu)化
①數(shù)據(jù)庫(kù)(表)本身設(shè)計(jì)要規(guī)范(至少要求滿足3NF) 3范式
②創(chuàng)建適當(dāng)索引(主鍵索引,普通索引,唯一索引,全文索引sphinx->coreseek,空間索引)
③優(yōu)化SQL語(yǔ)句->如何定位慢查詢
④使用分表技術(shù)[思路:大->小],水平分割,垂直分割
⑤創(chuàng)建適當(dāng)存儲(chǔ)過(guò)程,觸發(fā)器,自定義函數(shù),視圖(1,模塊化編程,2提高數(shù)據(jù)庫(kù)的訪問(wèn)速度)
⑥優(yōu)化my.ini文件(調(diào)整mysql的各級(jí)緩存.)
⑦升級(jí)mysql硬件和軟件 , 操作系統(tǒng)64, mysql就使用64
未完待續(xù)...
我們的表要滿足1NF基礎(chǔ)上,才可以談滿足2NF,目前最高級(jí)6NF,對(duì)PHP網(wǎng)站說(shuō),我們只要滿足3NF。
比如mysql, oracle, sql server ,postgresql,informix,DB2
面向?qū)ο蠛图蠑?shù)據(jù)庫(kù).
mongodb數(shù)據(jù)庫(kù)面向文檔
所謂1NF:屬性(列)具有原子性,不可在分割,還有就是把同一張表不可以有兩個(gè)相同列.
所謂2NF:說(shuō)表的記錄具有唯一性.,即不能出現(xiàn)完全相同的兩條記錄.一般說(shuō),通過(guò)設(shè)置主鍵即可.
注意;主鍵最好是非業(yè)務(wù)邏輯主鍵,使用自增長(zhǎng).
3NF要保證數(shù)據(jù)沒有冗余.即如果數(shù)據(jù)可能通過(guò)顯示或者隱式的推導(dǎo)出,就不要單獨(dú)設(shè)計(jì)一列.
比如下圖就是滿足3NF:
但是說(shuō)明; 有時(shí)我們?cè)O(shè)計(jì)表的時(shí)候,可能會(huì)使用反3NF.,舉例:
上面的相冊(cè)表的設(shè)計(jì)就使用到了反3NF,但是他提高了效率
使用 showstatus 可以參考到mysql的各個(gè)參數(shù),我們需要掌握的是以下參數(shù), 其它請(qǐng)參考手冊(cè).
比如 com_select com_update com_insert com_delete , 比如我們?cè)谶x擇表究竟時(shí)候用MyISAM 還是 InnoDB ,可以看看該網(wǎng)站是以讀和寫操作為主,則可以使用MyISAM.
這里注意當(dāng)我們使用 showstatus 來(lái)查詢參數(shù)時(shí),默認(rèn)是當(dāng)前會(huì)話.
show session status like xxxx
如果你要查看從數(shù)據(jù)庫(kù)啟動(dòng)到現(xiàn)在狀態(tài)
show global status like xxx
show status like ‘connections’ 可以查看當(dāng)前連接的數(shù)量.
表示數(shù)據(jù)庫(kù)啟動(dòng)時(shí)間
show status like ‘slow_queries’
顯示慢查詢次數(shù), 默認(rèn)情況下mysql認(rèn)為慢查詢時(shí)間是10s
我們使用兩個(gè)方法,蠕蟲復(fù)制,可以構(gòu)建大表,但是測(cè)試效果不好.
使用存儲(chǔ)過(guò)程來(lái)創(chuàng)建海量表
模擬一個(gè)雇員管理系統(tǒng)
#模擬一個(gè)雇員管理系統(tǒng)
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 ;
#創(chuàng)建表EMP雇員
CREATE TABLE emp
(empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, /*編號(hào)*/
ename VARCHAR(20) NOT NULL DEFAULT "", /*名字*/
job VARCHAR(9) NOT NULL DEFAULT "",/*工作*/
mgr MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,/*上級(jí)編號(hào)*/
hiredate DATE NOT NULL,/*入職時(shí)間*/
sal DECIMAL(7,2) NOT NULL,/*薪水*/
comm DECIMAL(7,2) NOT NULL,/*紅利*/
deptno MEDIUMINT UNSIGNED NOT NULLDEFAULT 0 /*部門編號(hào)*/
)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;
#測(cè)試數(shù)據(jù)
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 $$
#創(chuàng)建一個(gè)函數(shù),可以返回一個(gè)隨機(jī)的字符串
create function rand_string(n INT)
returns varchar(255) #該函數(shù)會(huì)返回一個(gè)字符串
begin
#定義了一個(gè)變量 chars_str,類型 varchar(100)
#默認(rèn)給 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 $$
#這里我們又自定了一個(gè)函數(shù),返回一個(gè)隨機(jī)的部門號(hào)
create function rand_num( )
returns int(5)
begin
declare i int default 0;
set i = floor(10+rand()*500);
return i;
end $$
#隨即添加雇員[光標(biāo)] 400w,Mysql開發(fā)中,可以在存儲(chǔ)過(guò)程中調(diào)用你自己
#編寫的函數(shù)
create procedure insert_emp(in start int(10),in max_num int(10))
begin
declare i int default 0;
#set autocommit =0 把a(bǔ)utocommit設(shè)置成0
#autocommit = 0 含義: 不要自動(dòng)提交
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 $$
調(diào)用存儲(chǔ)過(guò)程添加400w數(shù)據(jù)
call insert_emp(100001,4000000);
步驟
①在默認(rèn)情況下,mysql是不會(huì)記錄慢查詢, 所以我們要使用另外一種方式啟動(dòng)mysql,指令: cmd>bin\mysqld.exe � safe-mode �slow-query-log
這樣就會(huì)在mysql 的 data目錄,生成一個(gè)日志文件,該文件可以把慢查詢語(yǔ)句記錄到文件.
②為了測(cè)試我們修改默認(rèn)的慢查詢時(shí)間
show variables like ‘long_query_time’ 【查詢當(dāng)前慢查詢時(shí)間】
set long_query_time=1
③當(dāng)執(zhí)行一個(gè)時(shí)間超過(guò)1秒的sql語(yǔ)句,就會(huì)被記錄下來(lái).
# Query_time: 1.500000 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 4000000
use temp100;
SET timestamp=1371870578;
select * from emp whereempno=456784;
④分析慢查詢時(shí)如何導(dǎo)致explain 工具
基本語(yǔ)法: explain sql \G
可以來(lái)分析mysql是如何執(zhí)行你的sql語(yǔ)句
細(xì)致的說(shuō)明請(qǐng)參考優(yōu)化.ppt
⑤解決問(wèn)題: 我們發(fā)現(xiàn)目前這個(gè)語(yǔ)句沒有使用到索引,因此我們先考慮使用索引解決.
創(chuàng)建普通索引: CREATE INDEX 索引名 ON 表名(列)
⑥看看此時(shí)速度怎樣
圖:
①當(dāng)一個(gè)表的存儲(chǔ)引擎是MyISAM 時(shí),對(duì)應(yīng)三個(gè)文件
表名.frm 【表的結(jié)構(gòu)】
表名.myd 【表的數(shù)據(jù)】
表名.myi 【索引的數(shù)據(jù)】
未完待續(xù)...
總結(jié)
以上是生活随笔為你收集整理的mysql数据库优化韩顺平_韩顺平 Mysql数据库优化(一) 优化概述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql慢查询单位_MySQL慢查询
- 下一篇: linux cmake编译源码,linu