mysql 優化(一)

數據庫的操做愈來愈成爲整個應用的瓶頸,mysql優化是提升應用性能的重中之重,今天來說講最近研究的mysql 的一些性能優化php

Mysql的性能優化mysql

(一) 開啓查詢緩存優化的你查詢速度sql

如何開啓mysql的查詢緩存?你的mysql數據庫是否支持mysql查詢緩存?? (查詢緩存是一把雙刃劍,這裏就很少說了)數據庫

查詢緩存的工做流程:緩存

1. 服務器接收SQL,以SQL和一些其餘條件爲key查找緩存表(額外性能消耗)性能優化

2. 若是找到了緩存,則直接返回緩存(性能提高)服務器

3. 若是沒有找到緩存,則執行SQL查詢,包括原來的SQL解析等.網絡

4. 執行完SQL查詢結果之後,將SQL查詢結果存入緩存表(額外性能消耗)mysql優化

打開命令行終端 輸入 show variables like "%query_cache%"; 查看你是否開啓緩存php7

這裏的參數

have_query_cache: 你的mysql版本是否支持查詢緩存

query_cache_size : 緩存使用的總內存空間大小,單位是字節,這個值必須是1024的整數倍,不然MySQL實際分配可能跟這個數值不一樣

query_cache_type: 緩存的方式 有三個值 1) OFF: 關閉  2) ON: 老是打開 3) DEMAND: 只有明確寫了SQL_CACHE的查詢纔會吸入緩存

query_cache_min_res_unit: 分配內存塊時的最小單位大小

若是你的 query_cache_type =0  or query_chache_size =0 那麼表示沒有開啓緩存,能夠修改配置文件來開啓

當有不少相同的查詢被執行了屢次的時候,這些查詢結果會被放到一個緩存中,這樣,後續的相同的查詢就不用操做表 而直接訪問緩存結果了。

若是你的查詢條件有包含一些mysql的內置函數 好比 有時間 now() ,rand()等,那麼講不會緩存.

比較一下下面我執行的sql語句,當我開啓查詢緩存的時候 第一次執行所消耗的時間跟第二次執行所消耗的時間 以及相同查詢語義可是大小寫不同.(sql語句絕對相等)

 

 

(2) EXPLAIN你的查詢語句

EXPLAIN關鍵字可以讓你知道索引的使用,如何搜索數據的,掃描行數等等

能夠幫助你分析你SELECT 語句的瓶頸所以能夠優化你的SELECT語句

選擇一個複雜的sql語句

能夠看到mysql是怎麼樣處理你的sql語句

select_type: 有三個參數(simple,primary, union,dependent union,union result)  simple 它表示簡單的select,沒有union和子查詢(這裏只介紹simple)

table : 出自哪一張表

type :顯示的訪問類型,從性能最好到最壞以此是 system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

表中只有一行;const類型的特例

 

2)const:  表中最有有一行匹配,const用戶比較primary key或者unique索引,由於只有一行,因此很快

 

3)eq_ref :   mysql手冊是這樣說的:"對於每一個來自於前面的表的行組合,從該表中讀取一行。這多是最好的聯接類型,除了const類型。它用在一個索引的全部部分被聯接使用而且索引是UNIQUE或PRIMARY KEY"。即比較帶索引的列

4)ref : 對於每一個來自於前面的表的行組合,全部有匹配索引值的行將從這張表中讀取。這裏的索引不包括 primary和unique.

5)rang : 給定範圍內的索引,如 EXPLAIN SELECT * FROM user WHERE id IN (1,5) 或者是 BETWEEN

6)ALL : 全表掃描

possible_key : 顯示 使用的哪一個索引在該表中找到行 

key : 該查詢時所用到的索引

key_len : 使用索引的長度

ref : ref列顯示使用哪一個列或常數與key一塊兒從表中選擇行。

rows : 顯示查詢時掃描的行數,值越大越很差,因此根據這個能夠判斷mysql語句的好壞以及創建索引優化

extra: 額外的信息

能夠根據EXPLAIN你SELECT的查詢語句 進行相關的優化

 

(3) 爲你的表合理的創建索引

這裏爲何是合理呢,索引不是建得越多就越好,索引太多 對於 UPDATE DELETE INSERT 的效率都會有影響,

上面提到的EXPLAIN SELECT 語句咱們能夠進行分析

在table user(及table a)中 它的掃描行數是 180207行.並且是全表掃描,沒有用到索引,

在命令行中咱們來執行如下該sql,查詢的時間是0.63sec

咱們能夠給user表中的school_id加個索引 CREATE INDEX schoolIndex ON `user`(school_id);

 

這時來看一下查詢的時間和EXPLAIN SELECT 語句,

 

 總結:能夠很明顯的看出 執行時間大大減小了,並且在EXPLAIN中能夠看到 type相比於以前的ALL 如今是ref (索引) ,row也相比於180207行到2385行 性能大大的提高了許多

另外須要注意的是:當你的WHERE 後面的條件是 a.name like %陳%; 這樣是不會的查詢語句 就算你給name加一個索引 也會沒有意義.

一、創建多表(三個表或以上)關聯視圖時,若是是主表和副表都有的字段,儘可能使用主表的字段(特別是主表的主鍵)
二、副表的字段(不管是普通字段仍是主鍵、索引字段)做爲查詢條件對查詢都沒有幫助,都需進行全表檢索

 

(4)若是查詢一條數據的時候使用limit

舉個例子 :  SELECT * FROM user WHERE name='vDobgB';

當你知道 name='vDobgB'在數據庫中只有一條數據的時候使用limit會大大提高效率,這個時候mysql找到該行的時候就會返回這條數據,而不會繼續往下查找

 

(5)在join表的時候 鏈接條件的字段類型,應當一致,而且將其索引

若是你的應用中使用到了不少錶鏈接查詢,應該確認表與錶鏈接字段已經創建了索引,而且兩個字段類型是一致的.

向我上面兩錶鏈接的字段類型都是int類型,且已經加了索引.若是你要把DECIMAL(小數)類型字段和int(整形)類型的字段鏈接在一塊兒,那麼Mysql就沒法使用它們的索引

 

(6)避免使用 SELECT *

從數據庫裏讀出越多的數據,那麼查詢就會變得越慢。而且,若是你的數據庫服務器和WEB 服務器是兩臺獨立的服務器的話,這還會增長網絡傳輸的負載。

應該養成,須要什麼數據就拿什麼數據

 

 

(7)創建主鍵索引 即id

爲每個表都創建主鍵索引 id,並且這個id仍是 AUTO_INCREMENT 最好是INT類型 ,

若是你有一張表name是惟一的,而且你給name這個字段設立爲主鍵,這樣效率會減低,由於使用VARCHAR類型的主鍵低於INT類型.

並且,在MySQL 數據引擎下,還有一些操做須要使用主鍵,在這些狀況下,主鍵的性能和設置變得很是重要,好比:mysql的分表, 集羣等

 

(8)某些狀況下使用ENUM而不是VARCHAR (可是也有一些人說慎用ENUM類型)

若是你的表中的某個字段 例如: 省份,而這個字段常常出現的且只會出現的只有 廣東省,福建省,海南省等國家的全部省份.

那麼你應該給該字段的類型應該是ENUM而不是VARCHAR.

ENUM 類型是很是快和緊湊的。在實際上,其保存的是TINYINT,但其外表上顯示爲字符串。

例如,指定爲 ENUM("one", "two", "three") 的一個列,能夠有下面所顯示的任一值。每一個值的索引值也以下所示:

索引值
NULL NULL
"" 0
"one" 1
"two" 2
"three" 3

 

 

 

 

 

 

(9) 使用PROCEDURE ANALYSE()取得建議

 

 其中 optimal_fieldtype會推薦咱們使用怎麼樣的數據類型,當表中數據了越大的時候,就越準確,可是不必定是徹底準確的,你須要思考..哈哈哈哈

 

 (10)創建表的時候使用NOT NULL,並且儘可能給表設定默認值

NULL 須要額外的空間,mysql的上的文檔是這麼說的

 若是你的表的字段是int 那麼應該給默認值 DEFAULT 0 ,若是是varchar類型 DEFAULT ' '

 

mysql的部分優化先暫時講這麼多,若是有疑惑的或者是有其餘看法的歡迎評論..

今天php7發佈了,php7的性能相比於原來提升了百分之40%-200%.

相關文章
相關標籤/搜索