mysql數據庫優化技術(1)


mysql優化是一個綜合性的技術,主要包括:

a、表的設計合理化(符合3NF);

b、添加適當的索引(index[四種]:普通索引、主鍵索引、唯一索引(unique)、全文索引;

c、分表技術(水平分割、垂直分割);

d、讀寫分離;

e、存儲過程(模塊化編程,可以提高速度);

f、對mysql配置優化:配置最大並發數(my.ini文件:max_connections最大並發數,一般網站應設置到1000左右,太大的話內存會受不了)、調整緩存大小;

gmysql服務器硬件的升級;

h、定時去清除不需要的數據,定時進行碎片整理(尤其是MyISAM存儲引擎)。


Ø 數據庫三層結構:PHP程序→dbms(數據庫管理系統,我們平常說的數據庫其實是這個)→數據庫(就是文件)。

Ø PHP程序發送sql語句,dbms進行編譯后,再執行,對從數據庫中返回的數據進行緩存,所以第二次sql請求時速度會變快。但是使用sql語句去操作,編譯會很耗時,我們可以事先把一些經常用的代碼在數據庫中進行編碼形成二進制,再直接調用,這個過程就是存儲過程。

Ø 符合3NF(范式)的表:表的范式,首先符合1NF,才能滿足2NF,進一步滿足3NF

Ø 1NF:即表的列具有原子性,不可再分解,即列的信息,不能再分解。只要數據庫是關系型數據庫(mysqlOracledb2sql serverinformixsysbase),就自動滿足1NF

Ø 2NF:表的記錄是唯一的,滿足2NF,通常我們通過設計一個主鍵來實現。(主鍵:一般來講不含業務邏輯,一般是自增的。因為主鍵不含業務邏輯,數據較穩定)

Ø 3NF:即表中不要有冗余數據,就是說,表的信息如果能推導出來,就不應該單獨的設計一個字段來存放。下圖不符合3NF


Ø 反3NF:(相冊表的瀏覽次數是對應photo表的圖片瀏覽次數之和,為了提升響應速度,在每次瀏覽圖片增加圖片瀏覽次數的同時,相冊表也同時添加瀏覽次數。雖然相冊的瀏覽次數可以通過photo表推導出來,但是如果圖片太多,雙表查詢時速度就會慢,通過設計字段views就可以解決,所以必要的數據冗余也是允許的)


Ø SQL語句優化:如何從一個大型項目中快速定位執行速度慢的語句(定位慢查詢)?

Ø 常用語句:show statusshow status like uptime 查看MySQL啟用多長時間;show [session|global] status like com_select  show status like com_update (默認參數是session會話,指取出當前窗口的執行,global取出從mysql啟動到現在的執行次數查看對應語句執行了多少次(存儲引擎的選擇偏向於參考哪個操作執行的多)show status like connections 查看試圖連接mysql服務器的次數;show status like slow_queries(顯示慢查詢次數)

Ø 慢查詢(默認情況,mysql認為10秒是一個慢查詢)優化:定位慢查詢(構建一個大表->存儲過程;修改mysql的慢查詢:顯示慢查詢值show variables like long_query_time,修改值set long_query_time=1

Ø 把慢查詢的sql語句記錄到我們的一個日志中(默認下mysql不會記錄慢查詢,需要在mysql啟動時指定記錄慢查詢才行)。如果啟用了慢查詢記錄日志,默認把這個文件放在my.ini文件記錄的位置,如:datadir=d:/wamp/bin/mysql/mysql5.6.12/data(這個地址不要輕易去修改)

Ø 數據庫中可以有多個數據對象:表、存儲過程、視圖、函數、觸發器

Ø dual亞元表,即一個空表。select rand_string(6) from dual;


優化問題:

Ø 通過explain語句可以分析,mysql如何執行sql語句

Ø 建立適當索引:

Ø 1、添加索引:

Ø 主鍵索引的添加:當一張表,把某個列設為主鍵的時候,該列就是主鍵索引。創建表后再添加索引:alter table 表名 add primary key (列名)。建立索引是有開銷的。不能為空,也不能重復。

Ø 為什么創建主鍵索引后速度會變快:沒建立索引之前,dbms是按照給定的條件(如id=2)一個一個的順序去查找。而建立索引后,可以利用二叉樹算法(或哈希算法),建立索引文件。二叉樹(BTREE)的效率log2N

Ø 普通索引的添加:普通索引的創建時,先建表,再創建普通索引。create table aaa....create index 索引名 on ()

Ø 全文索引的添加:全文索引主要針對文本的檢索,全文索引只對MyISAM有效,目前只針對英文有效(sphinxcoreseek)技術處理中文),對停用詞不建索引

  CREATE TABLE articles (

   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,

   title VARCHAR(200),

   body TEXT,

   FULLTEXT (title,body)

   )engine=myisam charset utf8;

Ø 使用全文索引:錯誤用法 select * from articles where body like ‘%mysql%’;(不會使用全文索引);正確用法:select * from articles where match(title,body) against (‘mysql’)

Ø 唯一索引的添加:當表的某列被指定為unique約束時,這列就是一個唯一索引(也采用了二叉樹的算法)。唯一索引是不能重復的,但是可以為空(NULL可以有多個,’’空字符串只能有一個);創建表后再添加唯一索引:create unique index 索引名 on 表名(列名)

Ø 復合索引:索引作用在多列上。alter table 表名 add index 索引名 (列名1,列名2...)

Ø explain:了解sql語句的執行情況




Ø 2、查詢索引:desc 表名(該方法的缺點是不能夠顯示索引的名字)、show index(es) from 表名(\G)show keys from 表名(\G)

Ø D:\wamp\bin\mysql\mysql5.6.12\data\可以看到這個目錄中,一個數據庫有一個文件夾,使用InnoDB建立的表由三個文件構成:


使用MyASIN引擎建立的表一般只有.frm文件,而起數據反正上以及目錄的。

.frm表示表的結構、.MYD表示表的數據、MYI表示表的索引.建立索引后.MYI文件會 變大。

Ø 3、刪除索引alter table 表名 drop index 索引名;如果刪除的是主鍵索引,還可以:alter table 表名 drop primary key;

Ø 4、修改索引:一般是先刪除,再重新創建。

Ø 使用索引的注意事項:磁盤占用;對dml(update delete insert)語句的效率影響,變慢:因為在增刪改的時候,索引文件會更新(如刪除一個記錄,對應二叉樹也應該刪除對應記錄),即使這樣使用索引利大於弊,大部分網站查詢多於增刪改。

Ø 哪些列上適合添加索引:肯定在where中經常使用;該字段的內容不是唯一的幾個值(sex);字段內容不是頻繁變化的。


Ø 使用索引時的注意事項:

Ø 1、對於創建的多列索引,只要查詢條件使用了最左邊的列,索引一般會被使用。

alter table dept add index myind (dnam,loc)//dnam是左邊的列,loc是右邊的列。

Ø 2、對於使用like的查詢,查詢如果是’%aaa’(%aaa%_aaa)不會使用到索引,’aaa%’會使用到索引(即,在like查詢時,關鍵字的首個字符是確定的,不能使用%_,如果前面有變化,則考慮全文索引)

Ø 3、如果條件中有or,所有使用到的字段都要建立索引(復合索引右邊的列也要),建議盡量避免使用or

Ø 4、如果列類型是字符串,那一定要在條件中將值使用單引號引用起來,否則不使用索引。(值如果是字符串,不使用單引號,直接報錯,如果是數字,不使用單引號不會報錯,因為會自動轉為字符串,但是無法使用索引)

Ø 5mysql會估計全表掃描比使用索引還快,則不使用索引。

Ø 查看索引使用的情況:show status like ‘handler_read%’

Ø 把一張表的數據導入到另一張表中,建議先禁用索引,要不然在導入數據的同時也會建立索引(不是重點)

Ø group by分組查詢時,默認分組后,還會自動排序(filesort),可能會降低速度。在group by后增加order by null 防止排序。

Ø 有些情況,可以使用連接代替子查詢,因為使用joinMySQL不需要在內存中創建臨時表。

簡單連接查詢:select * from dept,emp where dept.deptno=emp.deptno;

左外連接:select * from dept left join emp on dept.deptno=emp.deptno;

Ø 如何選擇MySQL的存儲引擎:

Ø myisam:如果表對事務要求不高,同時是以查詢和添加為主的,我們考慮使用myisam。比如bbs中的發帖表、回復表。

Ø InnoDB:對事務要求高,保存的數據都是重要數據,建議使用InnoDB。比如訂單表、賬戶表。

Ø Memory:比如我們數據變化頻繁,不需要入庫,同時又頻繁的查詢和修改,考慮使用。

myiasm數據查添加比InnoDB快,因為myisam直接在表尾插入,而InnoDB要先對數據進行事務安全的校驗,並進行一個適當的排序。


PHP開發中,通常不設置外鍵,通常是在程序中保證數據的一致。

Ø 如果數據庫存儲引擎是myisam,一定要定時進行碎片整理(要不然刪除的數據永遠不會刪除):optimize table tablename



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com