在上篇文章給大家介紹了mysql資料庫效能最佳化一,今天繼續接著上篇文章給大家介紹資料庫效能最佳化相關知識。具體內容如下所示:
建立適當的索引
說起提高資料庫效能,索引是最物美價廉的東西了。不用加記憶體,不用改程式,不用調sql,只要執行個正確的'create index',查詢速度就可能提高百倍千倍,這可真有誘惑力。可是天下沒有免費的午餐,查詢速度的提高是以插入、更新、刪除的速度為代價的,這些寫操作,增加了大量的I/O。
是不是建立一個索引就能解決所有的問題?ename上沒有建立索引會怎樣?
select * from emp where ename='研發部';
---測試案例命令如下 (最好以 select * from emp e,dept d where e.empno=123451 )
*添加主鍵
ALTER TABLE emp ADD PRIMARY KEY(empno);
*刪除主鍵
alter table emp drop primary key;
索引的原理說明
沒有索引為什麼會慢?
使用索引為什麼會快?
索引的代價
1、磁碟佔用
2、對dml(update delete insert)語句的效率影響
btree 方式檢索,演算法複雜度: log2N 次數
哪些列上適合添加索引
1、較頻繁的作為查詢條件欄位應該建立索引
select * from emp where empno = 1;
2、唯一性太差的欄位不適合單獨建立索引,即使頻繁作為查詢條件
select * from emp where sex = '男'
3、更新非常頻繁的欄位不適合建立索引
select * from emp where logincount = 1
4、不會出現在WHERE子句中的欄位不該建立索引
索引的類型
•主鍵索引,主鍵自動的為主索引 (類型Primary)
•唯一索引 (UNIQUE)
•普通索引 (INDEX)
•全文索引 (FULLTEXT) [適用於MyISAM] ——》sphinx + 中文分詞 coreseek [sphinx 的中文版 ]
•綜合使用=>複合索引
簡述mysql四種索引的區別
lPRIMARY 索引 =》在主鍵上自動建立
lUNIQUE 索引=> 只要是UNiQUE 就是Unique索引.(只能在欄位內容不重複的情況下,才能建立唯一索引)
lINDEX 索引=>就是普通索引
lFULLTEXT => 只在MYISAM 儲存引擎支援, 目的是全文索引,在內容系統中用的多, 在全英文網站用多(英文詞獨立). 中文資料不常用,意義不大,國內全文索引通常使用 sphinx來完成,全文索引只能在 char varchar text欄位建立.
全文索引案例
1.建立表
create table news(id int , title varchar(32),con varchar(1024)) engine=MyISAM;
2.建立全文索引
create fulltext index ful_inx on news (con);
3.插入資料
這裡要注意,對於常見的英文 fulltext 不會匹配,而且插入的語句本身是正確的.
'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表示沒有匹配到,或者你的詞是停止詞,是不會建立索引的.
使用全文索引,不能使用like語句,這樣就不會使用到全文索引了.
複合索引
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(列名,..); 聯合主鍵
刪除索引
DROP INDEX index_name ON tbl_name;alter table table_name drop index index_name; 刪除主鍵(索引)比較特別: alter table t_b drop primary key;
查詢索引(均可)
show index(es) from table_name;show keys from table_name;desc table_Name;
修改索引,我們一般是先刪除在重新建立.
查詢要使用索引最重要的條件是查詢條件中需要使用索引。
下列幾種情況下有可能使用到索引:
1,對於建立的多列索引,只要查詢條件使用了最左邊的列,索引一般就會被使用。
2,對於使用like的查詢,查詢如果是 '%aaa' 不會使用到索引, 'aaa%' 會使用到索引。
下列的表將不使用索引:
1,如果條件中有or,即使其中有條件帶索引也不會使用。
2,對於多列索引,不是使用的第一部分,則不會使用索引。
3,like查詢是以%開頭
4,如果列類型是字串,那一定要在條件中將資料使用引號引用起來。否則不使用索引。(添加時,字串必須'')
5,如果mysql估計使用全表掃描要比使用索引快,則不使用索引。
測試案例(就在前面的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 ; --放入資料,前面應該已經添加了,如果沒有則需要重新添加--測試開始.
添加一個主鍵索引
alter table dept add primary key (deptno)
--測試語句
explain select * from dept where deptno=1;
結果是:
mysql> explain select * from dept where deptno=1;*************************** 1. row ***************************id: 1select_type: SIMPLEtable: depttype: constpossible_keys: PRIMARYkey: PRIMARYkey_len: 3ref: constrows: 1Extra:1 row in set (0.00 sec)
--建立多列索引
alter table dept add index myind (dname,loc);
--證明對於建立的多列索引,只要查詢條件使用了最左邊的列,索引一般就會被使用
explain select * from dept where dname='研發部'; 會顯示使用到了索引myindexplain select * from dept where loc='MsBDpMRX'; 不會顯示使用到了索引myind
--對於使用like的查詢
explain select * from dept where dname like '%研發部'; 不會顯示使用到了索引myindexplain select * from dept where dname like '研發部%'; 會顯示使用到了索引myind
--如果條件中有or,即使其中有條件帶索引也不會使用
--為了示範,我們把複合索引刪除,然後只在dname上加入索引.
alter table dept drop index myindalter table dept add index myind (dname)explain select * from dept where dname='研發部' or loc='aa';-- 就不會使用到dname列上的
--如果列類型是字串,那一定要在條件中將資料使用引號引用起來。否則不使用索引
select * from dept from dname=1234; //不會使用到索引select * from dept from dname='1234'; //會使用到索引
查看索引的使用方式
show status like 'Handler_read%';
大家可以注意:
handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數。
handler_read_rnd_next:這個值越高,說明查詢低效。
* 這時我們會看到handler_read_rnd_next值很高,為什麼,這是因為我們前面沒有加索引的時候,做過多次查詢的原因.
常用SQL最佳化
大批量插入資料(MySql管理員) 瞭解
對於MyISAM:
alter table table_name disable keys;loading data//insert語句;alter table table_name enable keys;
對於Innodb:
1,將要匯入的資料按照主鍵排序
2,set unique_checks=0,關閉唯一性校正。
3,set autocommit=0,關閉自動認可。
最佳化group by 語句
預設情況,MySQL對所有的group by col1,col2進行排序。這與在查詢中指定order by col1, col2類似。如果查詢中包括group by但使用者想要避免排序結果的消耗,則可以使用order by
null禁止排序
有些情況下,可以使用串連來替代子查詢。
因為使用join,MySQL不需要在記憶體中建立暫存資料表。(講解)
如果想要在含有or的查詢語句中利用索引,則or之間的每個條件列都必須用到索引,如果沒有索引,則應該考慮增加索引(與環境相關 講解)
select * from 表名 where 條件1='' or 條件2='tt'explaine select * from dept group by dname; =>這時顯示 extra: using filesort 說明會進行排序explaine select * from dept group by dname order by null =>這時不含有顯示 extra: using filesort 說明不會進行排序
***有些情況下,可以使用串連來替代子查詢。因為使用join,MySQL不需要在記憶體中建立暫存資料表
explain select * from emp , dept where emp.deptno=dept.deptno;
和下面比較就可以說明問題!!
explain select * from emp left join dept on emp.deptno=dept.deptno;
選擇合適的儲存引擎
MyISAM:預設的MySQL儲存引擎。如果應用是以讀操作和插入操作為主,只有很少的更新和刪除操作,並且對事務的完整性要求不是很高。其優勢是訪問的速度快。
InnoDB:提供了具有提交、復原和崩潰恢複能力的事務安全。但是對比MyISAM,寫的處理效率差一些並且會佔用更多的磁碟空間。
Memory:資料存在記憶體中,服務重啟時,資料丟失
MyISAM: 在插入資料時,預設放在最後. ,刪除資料後,空間不回收.(不支援事務和外鍵)
InnoDB 支援事務和外鍵
對應我們程式員說,常用的儲存引擎主要是 myisam / innodb / memory,heap 表
如果選用小原則:
1.如果追求速度,不在乎資料是否一直把儲存,也不考慮事務,請選擇 memory 比如存放使用者線上狀態.
2.如果表的資料要持久儲存,應用是以讀操作和插入操作為主,只有很少的更新和刪除操作,並且對事務的完整性要求不是很高。選用MyISAM
3.如果需要資料持久儲存,並提供了具有提交、復原和崩潰恢複能力的事務安全,請選用Innodb
選擇合適的資料類型
在精度要求高的應用中,建議使用定點數來儲存數值,以保證結果的準確性。deciaml 不要用float
對於儲存引擎是MyISAM的資料庫,如果經常做刪除和修改記錄的操作,要定時執行optimize table table_name;功能對錶進行磁碟重組。
日期類型要根據實際需要選擇能夠滿足應用的最小儲存的早期類型
create table bbs(id int ,con varchar(1024) , pub_time int);date('Ymd',時間-3*24*60*60); 2038年-1-19
對於使用浮點數和定點數的案例說明
create table temp1( t1 float(10,2), t2 decimal(10,2));insert into temp1 values(1000000.32,1000000,32); 發現 t1 成了 1000000.31 所以有問題.
對於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;--複製delete from temp2 where id=1; 發現 該表對於的資料檔案沒有變小
定期執行 optimize table temp2 發現表大小變化,磁碟重組完畢
&&對於InnoDB它的資料會存在data/ibdata1目錄下,在data/資料庫/只有一個 *.frm表結構檔案.
關於mysql資料庫效能最佳化二小編就給大家介紹到這裡,希望對大家有所協助!