mysql索引的使用及優化方法

上篇講了數據基本的語法及SQL語句,這篇講講MySQL的優化查詢及一些高級管理功能。

數據庫高級管理及優化

 

MySQL性能優化

優化MySQL數據庫是數據庫管理員和數據庫開發人員的必備技能。優化MySQL,一方面是找出系統的瓶頸,提高MySQL數據庫整體的性能;另一方面是合理設計結構和調整參數,以提高用戶操作響應的速度。同時還要儘可能節省系統資源,以便系統可以提供更大負荷的服務。

MySQL數據庫優化是多方面的,原則是減少系統的瓶頸,減少資源的佔用,提高系統的反應速度。例如,通過優化文件系統,提高磁盤的讀寫速度;通過優化操作系統調度策略,提高MySQL在高負荷情況下的負載能力;通過優化表結構、索引、查詢語句等,使查詢響應更快。我們這裏只講第三點

MySQL中可以使用show status語句查詢MySQL數據庫的一些性能參數。其語法如下:

Show status like ‘value’;

其中value是要查詢的參數值,常用的一些性能參數如下:

Connections :連接MySQL服務器的時間

Uptime MySQL服務器的上線時間

Slow_ queries :慢查詢的次數

Com_select : 查詢操作的次數

Com_insert :插入操作的次數

Com_update:更新操作的次數

Com_delete :刪除操作的次數

 

對數據庫的優化有倆個方面:優化查詢(使用索引、使用連接查詢代替子查詢)和優化數據庫表結構

優化查詢

使用MySQL自帶的關鍵字explaindescribedesc)可以對查詢語句進行分析 如下:

 

其中比較關鍵的是rows該參數十分重要代表了本次查詢遍歷了多少行數據。

使用索引進行查詢:

前面已經介紹過了索引的用法這裏不再贅述,只是比較一下使用索引與不使用索引查詢的區別:

 

不用索引查詢成績表中成績爲90的所有信息

 

Key代表的是使用索引的名字,這裏爲null表示沒有使用索引,rows9表示本次查詢遍歷了9行數據。

 

 

使用索引查詢成績表中成績爲90的所有信息

 

Key代表使用的索引名,rows2表示本次查詢只遍歷了2行(要知道我的成績表中總的數據量只有9條)與不用索引對比簡直天壤之別。

索引可以提高查詢速度,但並不是使用帶有索引的字段查詢時索引都會起作用,一下幾種情況索引不會起作用:

1、如果在成績表中給score字段設置索引,但查詢時where條件使用的是一個範圍而MySQL估計這個範圍的數據量大於整表的30% 便不會用索引而是全表掃描,如:

 

2、在子查詢中,主句連接的索引無效,子句連接的索引有效

如:select * from student where id in (select studentid from score where score>90);

即此處id的索引無效,studentid的索引有效,如圖

 

主句的keynull,子句的keystuid索引。

3、使用like關鍵字進行查詢時,如果匹配字符串的第一個字符爲“%”,索引不會起作用,
%”不在第一個位置索引纔會起作用

 

 

4、使用多列索引查詢語句

對於多列索引,只有在查詢條件中使用了這些字段中的第一個字段時,索引纔會被使用。

5、使用or關鍵字的查詢語句

查詢語句的條件中只有OR時,並且OR前後的倆個條件中的列都是索引時,查詢中才使用索引,否則不使用索引。

 

優化子查詢

使用連接查詢(join)代替子查詢可以提高查詢效率。

MySQL4.1版開始支持子查詢(一個查詢的結果作爲另一個select子句的條件),子查詢雖然靈活但執行效率不高,因爲使用子查詢時,MySQL需要爲內層查詢語句的查詢結果建立一個臨時表,然後外層查詢語句從臨時表中查詢記錄,查詢完畢後 再撤銷這些臨時表,因此子查詢的速度會相應的受到影響。而連接查詢不需要建立臨時表其查詢速度快於子查詢!

 

 

優化數據庫表結構

 

1、將字段較多的表分解成多個表

對於字段較多的表,如果有些字段的使用頻率很低,可以將這些字段分離出來形成新表。因爲當一個表的數據量很大時,會由於存在使用頻率低的字段而使查詢速度變慢。

2、增加中間表

對於經常需要聯合查詢的表,可以建立中間表以提高查詢效率。通過建立中間表,把需要經常聯合查詢的數據插入中間表,然後將原來的聯合查詢改爲對中間表的查詢,以此來提高查詢效率。

3、增加冗餘字段

設計數據庫表時應儘量遵循範式理論的規約,儘可能減少冗餘字段,讓數據庫表的設計看起來精緻、優雅。但是,合理地加入冗餘字段可以提高查詢速度。如:員工信息存儲在staff表中,部門信息存儲在department表中。通過staff表中的department_id字段與department表建立關係,如果要查詢一個員工所在的部門的名稱,必須從staff表中找到員工所在部門的編號(department_id),然後根據這個編號在department表中查找部門名稱,如果經常需要這個操作,連接查詢便會浪費很多時間。可以在staff表中增加一個冗餘字段department_name,該字段用於存儲員工所在部門的名稱,這樣就不用每次都進行連接查詢操作了。

4、優化插入記錄的速度

innoDB引擎的表常見的優化方法

(1)、禁用唯一性檢查

插入數據時,MySQL會對插入的記錄進行唯一性校驗。這種唯一性校驗會降低插入記錄的速度。爲了降低這種情況對查詢速度的影響可以在插入記錄之前禁用唯一性檢查,等到記錄插入完畢後再開啓。

Set  unique_check=0; 開啓唯一性檢查的語句如下:set  unique_checks=1;

(2)、禁用外鍵檢查

插入數據之前禁止對外鍵的檢查,數據插入完成之後再恢復對外鍵的檢查。

Set foreign_key_checks=0; 恢復外鍵檢查:set foreign_key_checks=1;

(3)、禁止自動提交

插入數據之前禁止事務的自動提交,數據導入之後,執行恢復自動提交操作。

禁止自動提交的語句 set autocommit=0;恢復自動提交:set autocommit=1;

 

Myisam引擎表常見的優化方法

(1)、禁用索引 alter table table_name disable keys

開啓索引 alter table table_name enable keys

(2)禁用唯一性檢查

(3)使用批量插入

(4)當需要批量導入數據時,使用load data infile

 

5、分析、檢查和優化表

MySQL提供了分析。檢查和優化表的語句。分析表主要是分析關鍵字的分佈,檢查表主要是檢查表是否存在錯誤,優化表主要是消除刪除或者更新造成的空間浪費。

(1)分析表:

innoDBmyisamBDB類型的表有效

Analyze table talbename;分析期間數據庫系統會爲表加一個只讀鎖。

(2)檢查表

CheckinnoDBmyisam類型的表有效

Check table tablename option={quick | fast | medium | extended | changed}

Quick:不掃描行,不檢查錯誤的連接

Fast:只檢查沒有被正確關閉的表

Changed:只檢查上次檢查後被更改的表和沒有被正確關閉的表

Medium:掃描行,以驗證被刪除的連接是有效的,也可以計算各行的關鍵字校驗和,並使用計算出的校驗和驗證這一點。

Extended:對每行的所有關鍵字進行全面的關鍵字查找,這可以確保表是100%一致的,但是用時較長。

(3)優化表

innoDBmyisam類型的表有效

Optimize table tablename  可以刪除和更新造成的文件碎片。

 

6、優化MySQL的參數

通過優化MySQL的參數可以提高資源利用率,從而達到提高MySQL服務器性能的目的。MySQL服務的配置參數都在my.cnf或者my.ini文件的【MySQL】組中,下面介紹對性能影響比較大的幾個參數:

Key_buffer_size : 表示索引緩衝區的大小。索引緩衝區所有的線程共享。增加索引緩衝區可以得到更好處理的索引。當然該值也不是越大越好,它的大小取決於內存的大小(如果該值太大,導致操作系統頻繁換頁,也會降低系統的性能)

Table_cache:表示同時打開的表的個數。這個值越大,能夠同時打開的表就越多,但同時打開的表越多會影響操作系統的性能。

Query_cache_size:表示查詢緩衝區的大小,該參數需要和query_cache_type配合使用。當query_cache_type的值是0時,所有的查詢都不使用查詢緩衝區。但是query_cache_type=0並不會導致MySQL釋放query_cache_size所配置的緩衝區的內存。當query_cache_type=1時,所有的查詢都將使用查詢緩衝區。除非在查詢語句中加select sql_no_cache * from tablename query_cache_type=2時,除非在查詢中使用sql_cache關鍵字,否則查詢不會使用緩衝區。使用查詢緩衝區可以提高查詢的速度,這種方式只適用修改操作少並且經常執行相同的查詢操作的情況。

Sort_buffer_size:表示排序緩衝區的大小,這個值越大進行排序的速度越快。

Read_buffer_size:表示每個線程連續掃描時爲掃描的每個表分配的緩衝區的大小。當線程從表中連續讀取數據時會用到該緩衝區。

Read_rnd_buffer_size:表示爲每個線程保留的緩存區的大小,與Read_buffer_size相似。但主要用於存儲按特定順序讀取出來的記錄。

Innodb_buffer_pool_size:表示InnoDB類型的表和索引的最大緩存。這個值越大,查詢的速度就會越快,但這個值太大會影響操作系統的性能。

Max_connections:表示數據庫的最大連接數。這個數據不是越大越好,因爲這些鏈接會浪費內存資源,過多的連接可能會導致MySQL服務器僵死。

Innodb_flush_log_at_trx_commit:表示何時將緩衝區的數據寫入日誌文件,並且將日誌文件寫入磁盤。該參數對於innoDB引擎非常重要。該參數有3個值,分別爲012.值爲0時表示每隔一秒將數據寫入日誌文件並將日誌寫入磁盤;值爲1時表示每次提交事務時將數據寫入日誌文件並將日誌文件寫入磁盤;值爲2時表示每次提交事務時將數據寫入磁盤,每隔一秒將日誌文件寫入磁盤。該參數的默認值爲1,值爲1時安全性最高,但是每次事務提交或事務外的指令都需要把日誌寫入硬盤,是比較費時的;值爲0時更快一些,但安全方面比較差;值爲2時日誌仍然會每秒都寫入硬盤,所以即使出現故障,一般也不會丟失超過1~2秒的更新。

Back_log:表示在MySQL暫時停止回答新請求之前的短時間內,多少個請求可以被存在堆棧中。換句話說,該值表示到來的TCP/IP連接的偵聽隊列的大小。

Interactive_timeout:表示服務器在關閉連接前等待行動的秒數。

Sort_buffer_size:表示每個需要進行排序的線程分配的緩衝區的大小,增加這個參數可以提高order bygroup by操作的速度。

Thread_cache_size:表示可以複用的線程的數量。

Wait_timeout:表示服務器在關閉一個連接時等待行動的秒數。

 

數據庫備份

1、使用mysqldump命令備份

MysqldumpMySQL提供的一個非常有用的數據備份工具,執行MySQLdump命令時,可以將數據備份成一個文本文件。

對整個數據庫備份語法爲:mysqldump -u username -p dbname >filename.sql

例如:mysqldump -u root -p feng_test > d:feng.sql

對某張表備份語法爲:mysqldump -u username -p dbname tablename > filename.sql

備份多個數據庫:mysqldump -u username -p --databases booksdb test > filename.sql(備份booksdbtest數據庫)

另外--all-databases參數可以備份系統中所有的數據庫

 

還原備份:mysql -u  username -p dbname <  filename.sql

如果已經登錄了就可以使用:source filaname.sql

 

2、直接複製數據文件

3、Mysqlhotcopy快速備份與恢復

該方法是備份數據庫或單個表的最快途徑,但只能備份MYISAM類型的表!

test數據庫備份到/user/backup目錄下:

Mysqlhotcopy  -u  root -p test /user/backup

恢復數據:

 cp  -r  /usr/backup/test  usr/local/mysql/data

 

數據庫日誌

 

MySQL有四類日誌

錯誤日誌:記錄啓動、運行或停止MySQL服務時出現的問題

查詢日誌:記錄建立的客戶端連接和執行的語句

二進制日誌:記錄所有更改數據的語句,可用於數據複製

慢查詢日誌:記錄執行時間超過long_query_time的所有查詢或不使用索引的查詢。

1、二進制日誌:

二進制日誌主要記錄MySQL數據庫的變化。二進制日誌以一種有效的格式,並且是事務安全的方式包含更新日誌中可用的所有信息。二進制日誌包含所有更新了數據或者已經潛在更新了數據的語句。語句以“事件”的形式保存,描述數據更改。

啓動和設置二進制日誌

默認情況下,二進制日誌是關閉的,可以通過修改MySQL的配置文件來啓動和設置二進制日誌。My.ini文件中[mysqld]組下面有如下幾個設置是關於二進制日誌的:

Log-bin [=path/ [filename] ]

Expire_logs_days = 10

Max_binlog_size = 100M

Log-bin定義開啓二進制日誌,path表明日誌文件所在的目錄路徑;filename指定了日誌文件的名稱。

Expire_logs_days 定義了MySQL清除過期日誌的時間,即二進制日誌存活的日期

Max_binlog_size :定義了單個文件的大小,如果二進制日誌寫入的內容大小超過給定值,日誌就會發生滾動(關閉當前文件,重新打開一個新的日誌文件)

my.ini配置文件中的[mysqld]組下,添加上述幾個參數與參數值,關閉並重啓MySQL服務進程,即可打開二進制日誌。

使用show variables like   ‘log_%’;語句查詢日誌設置

使用show binary logs命令查看二進制日誌文件的個數及文件名

如:show binary logs

使用MySQLbinlog查看二進制日誌

如:Mysqlbinlog d:/mysql/log/binlog.000001

 

2、錯誤日誌

my.ini(或者my.cnf)文件下的【mysqld】下配置log-error,則可以啓動錯誤日誌。

Show variables like ‘log_error’;

 

3、通用查詢日誌

通用查詢日誌記錄MySQL所有用戶操作,包括啓動和關閉服務、執行查詢、更新語句等 。通過配置my.ini的【mysqld】組下加入log選項

 

4、慢查詢日誌

慢查詢日誌是記錄查詢時長超過指定時間的日誌

啓動:a)配置my.ini或者my.cnf中的log-slow-queries選項打開,

b) MySQL服務啓動時使用-log-slow-queries[=file_name]啓動慢查詢日誌

但都需要在配置文件中配置 long_query_time選項指定記錄閾值

Show variables like ‘slow_query_log%’;

Set global slow_query_log=1;開啓日誌

Set global long_query_time=4 設置閾值

select *from mysql.slow_log;

 

MySQL查詢緩存

MySQL服務器有一個重要的特徵是查詢緩存,緩存機制簡單的說就是緩存SQL語句和查詢的結果,如果運行相同的SQL語句,服務器會直接從緩存中取到結果,而不再需要再去解析和執行SQL語句。查詢緩存會存儲最新數據,而不會返回過期數據,當數據被修改後,在查詢緩存中的的任何相關數據均被清除。

如何使用:

1、設置query_cache_type ON

Set session query_cache_type=on ;

2、查看查詢緩存是否開啓

Select   @@query_cache_type;

3、查看系統變量have_query_cache是否爲YES,該參數表示MYSQL的查詢緩存是否可用

Show variables like ‘have_query_cache’;

4、查看系統變量query_cache_size 的大小,該參數表示數據庫分配給查詢緩存的內存大小,如果該參數的值設置爲0,那麼查詢緩存將不起作用。

Select   @@global.query_cache_size;

5、設置系統變量query_cache_size的大小

Set  @@global.query_cache_size = 1000000;

6、如果查詢結果很大導致緩存不了,那就得設置query_cache_limit參數的值,

Set  @@global.query_cache_limit = 2000000;

7、以如上方法設置緩存大小和緩存的最大值只對該次有用,如要永久設定則需修改 my.cnf配置文件:

[mysqld]

Port = 3306

Query_cache_size  =1000000

Query_cache_limit = 2000000

 

還有倆條使用的命令:show variables like  ‘%query_cache%’;查看緩存的相關參數

Show status like ‘qcache_hits’;   查看緩存命中的次數

SQL命令還是需要自己多敲多總結才能掌握!

 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章