1. 程式人生 > >mysql資料庫優化小結

mysql資料庫優化小結

一、常見資料庫的優化操作

1、表的設計要符合三正規化。

2、新增適當的索引,索引對查詢速度影響很大,必須新增索引。主鍵索引,唯一索引,普通索引,全文索引

3、新增適當儲存過程,觸發器,事務等。

4、讀寫分離(主從資料庫)

5、對sql語句的一些優化,(查詢執行速度比較慢的sql語句)

6、分表分割槽

分表:把一張大表分成多張表。分割槽:把一張表裡面的分配到不同的區域儲存,

7、對mysql伺服器硬體的升級操作。

二、適時提高效率

第一正規化

原子性:表裡面的欄位不能再分割,只要是關係型資料庫,就天然的自動滿足第一正規化。

關係型資料庫:(有行和列的概念)mysql,sql server,oracle,db2,infomix,sybase,postgresql

在設計時,先有庫-》表-》欄位-》具體記錄(內容):在儲存資料時,要設計欄位。

非關係型資料庫(泛指nosql資料庫):memcache/redis/momgodb/等

第二正規化

一個表中沒有完全相同的記錄,通過一個主鍵即能解決。

第三正規化

表中不能儲存冗餘資料。

 

三、定位慢查詢

慢查詢:找出在一個網站中,查詢速度比較慢的語句,可以開啟一個日誌檔案,記錄查詢速度比較慢的sql語句。在預設情況下,慢查詢日誌是關閉的,預設記錄時間是超過10秒 的sql語句。

1、以記錄慢查詢的方式來啟動mysql,

先關閉mysql,進入到mysql的安裝目錄。

關閉mysql服務:可以通過計算機-》管理->服務-》mysqld的服務名稱,單擊停止。

mysql的安裝目錄

通過慢查詢日誌定位執行效率較低的SQL語句。慢查詢日誌記錄了所有執行時間超過long_query_time所設定的SQL語句。

 

2、檢視慢查詢日誌的儲存路徑。

開啟了慢查詢日誌後,會建立一個慢查詢日誌檔案。該日誌檔案儲存在資料庫的目錄下,資料庫的目錄可以通過配置檔案檢視。

慢查詢日誌存放在mysql的data目錄下. 在my.ini配置檔案有data目錄

 

#Pathto the database root

datadir="C:/Documentsand Settings/All Users/Application Data/MySQL/MySQL Server 5.5/Data/“

 

3、程序測試:

檢視當前資料庫下慢查詢記錄時間:

show variables like ‘long_query_time’;

修改慢查詢時間:

set long_query_time=2;

 

通過如下的一個函式來進行測試:

benchmark(count,expr)函式可以測試執行count次expr操作需要的時間

 

一般情況下,出現查詢比較慢的語句,是沒有新增索引導致的。

 

四、索引

建立的測試表:

 

?

 

1

 

2

 

3

 

4

 

5

 

6

 

7

 

8

 

9

 

10

 

11

 

12

 

create

table  user(

 

   id int

primary  key  auto_increment,

 

   name

varchar(32) not

null  default  '',

 

   age tinyint unsigned not

null  default  0,

 

   email varchar(32) not

null  default  '',

 

   classid int

not  null  default  1

 

)engine myisam charset utf8;

 

insert

into  uservalues(null,'xiaogang',12,'[email protected]',4),

 

(null,'xiaohong',13,'[email protected]',2),

 

(null,'xiaolong',31,'[email protected]',2),

 

(null,'xiaofeng',22,'[email protected]',3),

 

(null,'xiaogui',42,'[email protected]',3);

 

 

 

建立一個班級表:

 

?

 

1

 

2

 

3

 

4

 

5

 

create

table  class(

 

   id int

not  null  default  0,

 

   classname varchar(32) not

null  default  ''

 

)engine myisam charset utf8;

 

insert

into  classvalues(1,'java'),(2,'.net'),(3,'php'),(4,'c++'),(5,'ios');

 

 

 

1、主鍵索引

可以在建立表的新增createtable emp(id int primary key)

可以在建立完表之後,新增:altertable tablename add primary key(列1,列2)

主鍵索引的特點:

(1)一個表中最多隻有一個主鍵索引

(2)一個主鍵索引可以指向多個列

(3)主鍵索引的列,不能有重複的值,也不能有null

(4)主鍵索引的效率高。

 

2、唯一索引

可以在建立表的時候新增:createtable emp(name varchar(32) unique)

在建完表之後,新增:

alter table tablename add unique [索引名](列名)

唯一索引的特點:

(1)一個表中可以有多個唯一索引

(2)一個唯一索引可以指向多個列 ,

比如alter tabletablename add unique [索引名](列1,列2)

(3)如果在唯一索引上,沒有指定not null,則該列可以為空,同時可以有多個null,

(4)唯一索引的效率較高。

 

3、普通索引

使用普通索引主要是提高查詢效率

 

新增alter table tablename add index [索引名](列1,列3)

 

4、全文索引

mysql自帶的全文索引mysql5.5不支援中文,支援英文,同時要求表的儲存引擎是myisam。如果希望支援中文,有兩個方案,

(1)使用aphinx中文版coreseek (來替代全文索引)

(2)外掛mysqlcft。

5、檢視索引

(1)show index from 表名

(2)show indexes from 表名

(3)show keys from 表名

(4)desc 表名

6、刪除索引

(1)主鍵索引的刪除:

alter table tablename drop primary key;要注意:在刪除主鍵索引時,要首先去掉auto_increment屬性。

(2)唯一索引的刪除

alter table tablename drop index 唯一索引的名字

 

(3)普通索引的刪除:

alter table tablename drop index 普通索引的名字

 

7、新增索引主要的問題:

(1)較頻繁的作為查詢條件欄位應該建立索引

select* from emp where empno = 1

唯一性太差的欄位不適合單獨建立索引,即使頻繁作為查詢條件

select* from emp where sex = '男‘

更新非常頻繁的欄位不適合建立索引

select* from emp where logincount = 1

(2)不會出現在WHERE子句中欄位不該建立索

索引是由代價的,雖然是查詢速度提高了,但是,會影響增該刪的效率。而且索引檔案會佔用空間。

 

五、explain的使用

 

該工具能夠分析sql執行效率,但是並不執行sql語句。主要是檢視sql語句是否用到索引。

語法:explain sql語句\G 或 desc sql語句\G

使用索引時:

 

沒有使用索引時:

 

explain工具的引數說明:

會產生如下資訊:

select_type:表示查詢的型別。

table:輸出結果集的表

type:表示表的連線型別

possible_keys:表示查詢時,可能使用的索引

key:表示實際使用的索引

key_len:索引欄位的長度

rows:掃描出的行數(估算的行數)

Extra:執行情況的描述和說明

 

六、索引

1、對於建立的多列(複合)索引,只要查詢條件使用了最左邊的列,索引一般就會被使用。

 

?

 

1

 

2

 

3

 

mysql> alter

table  user  add  index  (name,email);

 

Query OK, 5 rows

affected (0.08 sec)

 

Records: 5 Duplicates: 0  Warnings: 0

 

該查詢條件沒有使用到最左邊的列,所以沒有使用到索引。

 

 

該條件中使用了複合索引的最左邊的列,因此該查詢會使用到索引。

2、對於使用like的查詢,查詢如果是”%XXX”,不會使用到索引,‘XXX%’會使用到索引。

 

  

注意:在有些情況下,還是會用到like查詢,比如通過歌詞搜尋歌名,通過劇情搜尋電影名稱。藉助於工具,sphinx裡面的coreseek軟體。

 

3、如果條件中有or,則要求or的索引欄位都必須有索引,否則不能用到索引。

該email新增索引後,在測試,會用到索引

 

4、如果列型別是字串,一定要在條件中將資料使用引號引用起來,否則不使用索引。

 

5、優化group by語句

預設情況下, mysql對所有的group by col1,col2進行排序。這與在查詢中指定order by col1,col2型別,如果查詢中包括group by 但使用者想要避免排序結果的消耗,則可以使用order by null禁止排序。

 

 

6、當取出的資料量超過表中資料的20%,優化器就不會使用索引,而是全表掃描。掃描的行數太多了,優化器認為全表掃描比索引來的塊。

 

 

7、檢視索引的使用情況

 

注意:

handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數。

handler_read_rnd_next:這個值越高,說明查詢低效。

8、對應大批量插入資料

對於MyISAM:

先禁用索引:

alter table table_name disable keys;

loading data//insert語句; 執行插入語句

執行完成插入語句後,開啟索引,統一新增索引。

alter table table_name enable keys;

 

對於Innodb:

1,將要匯入的資料按照主鍵排序

2,setunique_checks=0,關閉唯一性校驗。

3,setautocommit=0,關閉自動提交。

七、併發處理的鎖機制

比如執行如下操作:

(1)從資料庫中取出id值,

(2)進行加1操作。

(3)修改完成後,再儲存到資料庫中。

比如原來 id的值為100,==》101

以上步驟執行100次,最後變成200

 

有兩個使用者同時執行的話。

a使用者:

100

101

 

b使用者:

100

101

 

通過鎖機制來進行解決

鎖機制:在執行時,只有一個使用者獲得鎖,其他使用者處於阻塞狀態,需要等待解鎖。

mysql 的鎖有以下幾種形式:

表級鎖:開銷小,加鎖快,發生鎖衝突的概率最高,併發度最低。myisam引擎屬於這種型別。

行級鎖:開銷大,加鎖慢,發生鎖衝突的概率最低,併發度也最高。innodb屬於這種型別。

1、表鎖的演示;

對myisam表的讀操作(加讀鎖),不會阻塞其他程序對同一表的讀請求,但會阻塞對同一表的寫請求。只有當讀鎖釋放後,才會執行其他程序的操作。

 

表新增讀鎖後,其他程序對該表只能查詢操作,修改時會被阻塞。

當前程序,能夠執行查詢操作,不能執行修改操作。不能對沒有鎖定的表進行操作。

鎖表的語法:

lock table 表名 read|write

也可以鎖定多個表,語法是:locktable 表1 read|wirte,表2 read|wirte

對myisam表的寫操作(加寫鎖),會阻塞其他程序對鎖定表的任何操作,不能讀寫,

表加寫鎖後,則只有當前程序對鎖定的表,可以執行任何操作。其他程序的操作會被阻塞。

 

2、行鎖的演示

innodb儲存引擎是通過給索引上的索引項加鎖來實現的,這就意味著:只有通過索引條件檢索資料,innodb才會使用行級鎖,否則,innodb使用表鎖。

行鎖的語法:

begin

sql語句

commit

開啟行鎖後,當前程序在針對某條記錄執行操作時,其他程序不能操作和當前程序相同id的記錄。