在上篇文章給大家介紹了mysql數(shù)據(jù)庫(kù)性能優(yōu)化一,今天繼續(xù)接著上篇文章給大家介紹數(shù)據(jù)庫(kù)性能優(yōu)化相關(guān)知識(shí)。具體內(nèi)容如下所示:
建立適當(dāng)?shù)乃饕?
說(shuō)起提高數(shù)據(jù)庫(kù)性能,索引是最物美價(jià)廉的東西了。不用加內(nèi)存,不用改程序,不用調(diào)sql,只要執(zhí)行個(gè)正確的'create index',查詢(xún)速度就可能提高百倍千倍,這可真有誘惑力??墒翘煜聸](méi)有免費(fèi)的午餐,查詢(xún)速度的提高是以插入、更新、刪除的速度為代價(jià)的,這些寫(xiě)操作,增加了大量的I/O。
是不是建立一個(gè)索引就能解決所有的問(wèn)題?ename上沒(méi)有建立索引會(huì)怎樣?
select * from emp where ename='研發(fā)部';
---測(cè)試案例命令如下 (最好以 select * from emp e,dept d where e.empno=123451 )
*添加主鍵
ALTER TABLE emp ADD PRIMARY KEY(empno);
*刪除主鍵
alter table emp drop primary key;
索引的原理說(shuō)明
沒(méi)有索引為什么會(huì)慢?
使用索引為什么會(huì)快?
索引的代價(jià)
1、磁盤(pán)占用
2、對(duì)dml(update delete insert)語(yǔ)句的效率影響
btree 方式檢索,算法復(fù)雜度: log2N 次數(shù)
哪些列上適合添加索引
1、較頻繁的作為查詢(xún)條件字段應(yīng)該創(chuàng)建索引
select * from emp where empno = 1;
2、唯一性太差的字段不適合單獨(dú)創(chuàng)建索引,即使頻繁作為查詢(xún)條件
select * from emp where sex = '男'
3、更新非常頻繁的字段不適合創(chuàng)建索引
select * from emp where logincount = 1
4、不會(huì)出現(xiàn)在WHERE子句中的字段不該創(chuàng)建索引
索引的類(lèi)型
•主鍵索引,主鍵自動(dòng)的為主索引 (類(lèi)型Primary)
•唯一索引 (UNIQUE)
•普通索引 (INDEX)
•全文索引 (FULLTEXT) [適用于MyISAM] ——》sphinx + 中文分詞 coreseek [sphinx 的中文版 ]
•綜合使用=>復(fù)合索引
簡(jiǎn)述mysql四種索引的區(qū)別
lPRIMARY 索引 =》在主鍵上自動(dòng)創(chuàng)建
lUNIQUE 索引=> 只要是UNiQUE 就是Unique索引.(只能在字段內(nèi)容不重復(fù)的情況下,才能創(chuàng)建唯一索引)
lINDEX 索引=>就是普通索引
lFULLTEXT => 只在MYISAM 存儲(chǔ)引擎支持, 目的是全文索引,在內(nèi)容系統(tǒng)中用的多, 在全英文網(wǎng)站用多(英文詞). 中文數(shù)據(jù)不常用,意義不大,國(guó)內(nèi)全文索引通常使用 sphinx來(lái)完成,全文索引只能在 char varchar text字段創(chuàng)建.
全文索引案例
1.創(chuàng)建表
create table news(id int , title varchar(32),con varchar(1024)) engine=MyISAM;
2.建立全文索引
create fulltext index ful_inx on news (con);
3.插入數(shù)據(jù)
這里要注意,對(duì)于常見(jiàn)的英文 fulltext 不會(huì)匹配,而且插入的語(yǔ)句本身是正確的.
'but it often happens that they are not above supporting themselves by dishonest means.which should be more disreputable.Cultivate poverty like a garden herb'
4.看看匹配度
mysql> select match(con) against('poverty') from news; +-------------------------------+ | match(con) against('poverty') | +-------------------------------+ | 0 | | 0 | | 0 | | 0.9853024482727051 | +------------------------------+
0表示沒(méi)有匹配到,或者你的詞是停止詞,是不會(huì)建立索引的.
使用全文索引,不能使用like語(yǔ)句,這樣就不會(huì)使用到全文索引了.
復(fù)合索引
create index 索引名 on 表名(列1,列2);
索引的使用
建立索引
create [UNIQUE|FULLTEXT] index index_name on tbl_name (col_name [(length)] [ASC | DESC] , …..); alter table table_name ADD INDEX [index_name] (index_col_name,...) 添加主鍵(索引) ALTER TABLE 表名 ADD PRIMARY KEY(列名,..); 聯(lián)合主鍵
刪除索引
DROP INDEX index_name ON tbl_name; alter table table_name drop index index_name; 刪除主鍵(索引)比較特別: alter table t_b drop primary key;
查詢(xún)索引(均可)
show index(es) from table_name; show keys from table_name; desc table_Name;
修改索引,我們一般是先刪除在重新創(chuàng)建.
查詢(xún)要使用索引最重要的條件是查詢(xún)條件中需要使用索引。
下列幾種情況下有可能使用到索引:
1,對(duì)于創(chuàng)建的多列索引,只要查詢(xún)條件使用了最左邊的列,索引一般就會(huì)被使用。
2,對(duì)于使用like的查詢(xún),查詢(xún)?nèi)绻?'%aaa' 不會(huì)使用到索引, 'aaa%' 會(huì)使用到索引。
下列的表將不使用索引:
1,如果條件中有or,即使其中有條件帶索引也不會(huì)使用。
2,對(duì)于多列索引,不是使用的第一部分,則不會(huì)使用索引。
3,like查詢(xún)是以%開(kāi)頭
4,如果列類(lèi)型是字符串,那一定要在條件中將數(shù)據(jù)使用引號(hào)引用起來(lái)。否則不使用索引。(添加時(shí),字符串必須'')
5,如果mysql估計(jì)使用全表掃描要比使用索引快,則不使用索引。
測(cè)試案例(就在前面的dept表上做演示.)
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 ; --放入數(shù)據(jù),前面應(yīng)該已經(jīng)添加了,如果沒(méi)有則需要重新添加 --測(cè)試開(kāi)始.
添加一個(gè)主鍵索引
alter table dept add primary key (deptno)
--測(cè)試語(yǔ)句
explain select * from dept where deptno=1;
結(jié)果是:
mysql> explain select * from dept where deptno=1; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: dept type: const possible_keys: PRIMARY key: PRIMARY key_len: 3 ref: const rows: 1 Extra: 1 row in set (0.00 sec)
--創(chuàng)建多列索引
alter table dept add index myind (dname,loc);
--證明對(duì)于創(chuàng)建的多列索引,只要查詢(xún)條件使用了最左邊的列,索引一般就會(huì)被使用
explain select * from dept where dname='研發(fā)部'; 會(huì)顯示使用到了索引myind explain select * from dept where loc='MsBDpMRX'; 不會(huì)顯示使用到了索引myind
--對(duì)于使用like的查詢(xún)
explain select * from dept where dname like '%研發(fā)部'; 不會(huì)顯示使用到了索引myind explain select * from dept where dname like '研發(fā)部%'; 會(huì)顯示使用到了索引myind
--如果條件中有or,即使其中有條件帶索引也不會(huì)使用
--為了演示,我們把復(fù)合索引刪除,然后只在dname上加入索引.
alter table dept drop index myind alter table dept add index myind (dname) explain select * from dept where dname='研發(fā)部' or loc='aa';-- 就不會(huì)使用到dname列上的
--如果列類(lèi)型是字符串,那一定要在條件中將數(shù)據(jù)使用引號(hào)引用起來(lái)。否則不使用索引
select * from dept from dname=1234; //不會(huì)使用到索引 select * from dept from dname='1234'; //會(huì)使用到索引
查看索引的使用情況
show status like 'Handler_read%';
大家可以注意:
handler_read_key:這個(gè)值越高越好,越高表示使用索引查詢(xún)到的次數(shù)。
handler_read_rnd_next:這個(gè)值越高,說(shuō)明查詢(xún)低效。
* 這時(shí)我們會(huì)看到handler_read_rnd_next值很高,為什么,這是因?yàn)槲覀兦懊鏇](méi)有加索引的時(shí)候,做過(guò)多次查詢(xún)的原因.
常用SQL優(yōu)化
大批量插入數(shù)據(jù)(MySql管理員) 了解
對(duì)于MyISAM:
alter table table_name disable keys; loading data//insert語(yǔ)句; alter table table_name enable keys;
對(duì)于Innodb:
1,將要導(dǎo)入的數(shù)據(jù)按照主鍵排序
2,set unique_checks=0,關(guān)閉唯一性校驗(yàn)。
3,set autocommit=0,關(guān)閉自動(dòng)提交。
優(yōu)化group by 語(yǔ)句
默認(rèn)情況,MySQL對(duì)所有的group by col1,col2進(jìn)行排序。這與在查詢(xún)中指定order by col1, col2類(lèi)似。如果查詢(xún)中包括group by但用戶(hù)想要避免排序結(jié)果的消耗,則可以使用order by
null禁止排序
有些情況下,可以使用連接來(lái)替代子查詢(xún)。
因?yàn)槭褂胘oin,MySQL不需要在內(nèi)存中創(chuàng)建臨時(shí)表。(講解)
如果想要在含有or的查詢(xún)語(yǔ)句中利用索引,則or之間的每個(gè)條件列都必須用到索引,如果沒(méi)有索引,則應(yīng)該考慮增加索引(與環(huán)境相關(guān) 講解)
select * from 表名 where 條件1='' or 條件2='tt' explaine select * from dept group by dname; =>這時(shí)顯示 extra: using filesort 說(shuō)明會(huì)進(jìn)行排序 explaine select * from dept group by dname order by null =>這時(shí)不含有顯示 extra: using filesort 說(shuō)明不會(huì)進(jìn)行排序
***有些情況下,可以使用連接來(lái)替代子查詢(xún)。因?yàn)槭褂胘oin,MySQL不需要在內(nèi)存中創(chuàng)建臨時(shí)表
explain select * from emp , dept where emp.deptno=dept.deptno;
和下面比較就可以說(shuō)明問(wèn)題!!
explain select * from emp left join dept on emp.deptno=dept.deptno;
選擇合適的存儲(chǔ)引擎
MyISAM:默認(rèn)的MySQL存儲(chǔ)引擎。如果應(yīng)用是以讀操作和插入操作為主,只有很少的更新和刪除操作,并且對(duì)事務(wù)的完整性要求不是很高。其優(yōu)勢(shì)是訪問(wèn)的速度快。
InnoDB:提供了具有提交、回滾和崩潰恢復(fù)能力的事務(wù)安全。但是對(duì)比MyISAM,寫(xiě)的處理效率差一些并且會(huì)占用更多的磁盤(pán)空間。
Memory:數(shù)據(jù)存在內(nèi)存中,服務(wù)重啟時(shí),數(shù)據(jù)丟失
MyISAM: 在插入數(shù)據(jù)時(shí),默認(rèn)放在最后. ,刪除數(shù)據(jù)后,空間不回收.(不支持事務(wù)和外鍵)
InnoDB 支持事務(wù)和外鍵
對(duì)應(yīng)我們程序員說(shuō),常用的存儲(chǔ)引擎主要是 myisam / innodb / memory,heap 表
如果選用小原則:
1.如果追求速度,不在乎數(shù)據(jù)是否一直把保存,也不考慮事務(wù),請(qǐng)選擇 memory 比如存放用戶(hù)在線狀態(tài).
2.如果表的數(shù)據(jù)要持久保存,應(yīng)用是以讀操作和插入操作為主,只有很少的更新和刪除操作,并且對(duì)事務(wù)的完整性要求不是很高。選用MyISAM
3.如果需要數(shù)據(jù)持久保存,并提供了具有提交、回滾和崩潰恢復(fù)能力的事務(wù)安全,請(qǐng)選用Innodb
選擇合適的數(shù)據(jù)類(lèi)型
在精度要求高的應(yīng)用中,建議使用定點(diǎn)數(shù)來(lái)存儲(chǔ)數(shù)值,以保證結(jié)果的準(zhǔn)確性。deciaml 不要用float
對(duì)于存儲(chǔ)引擎是MyISAM的數(shù)據(jù)庫(kù),如果經(jīng)常做刪除和修改記錄的操作,要定時(shí)執(zhí)行optimize table table_name;功能對(duì)表進(jìn)行碎片整理。
日期類(lèi)型要根據(jù)實(shí)際需要選擇能夠滿足應(yīng)用的最小存儲(chǔ)的早期類(lèi)型
create table bbs(id int ,con varchar(1024) , pub_time int); date('Ymd',時(shí)間-3*24*60*60); 2038年-1-19
對(duì)于使用浮點(diǎn)數(shù)和定點(diǎn)數(shù)的案例說(shuō)明
create table temp1( t1 float(10,2), t2 decimal(10,2)); insert into temp1 values(1000000.32,1000000,32); 發(fā)現(xiàn) t1 成了 1000000.31 所以有問(wèn)題.
對(duì)于optimize table 表名 演示
create table temp2( id int) engine=MyISAM; insert into temp2 values(1); insert into temp2 values(2); insert into temp2 values(3); insert into temp2 select * from temp2;--復(fù)制 delete from temp2 where id=1; 發(fā)現(xiàn) 該表對(duì)于的數(shù)據(jù)文件沒(méi)有變小
定期執(zhí)行 optimize table temp2 發(fā)現(xiàn)表大小變化,碎片整理完畢
&&對(duì)于InnoDB它的數(shù)據(jù)會(huì)存在data/ibdata1目錄下,在data/數(shù)據(jù)庫(kù)/只有一個(gè) *.frm表結(jié)構(gòu)文件.
關(guān)于mysql數(shù)據(jù)庫(kù)性能優(yōu)化二小編就給大家介紹到這里,希望對(duì)大家有所幫助!
Copyright ? 2019- 91gzw.com 版權(quán)所有 湘ICP備2023023988號(hào)-2
違法及侵權(quán)請(qǐng)聯(lián)系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市萬(wàn)商天勤律師事務(wù)所王興未律師提供法律服務(wù)