1. 程式人生 > >mysql 優化擴展

mysql 優化擴展

列表 insert 使用總結 部分 安全 結果 文本文 服務器 一行

一、SQL 優化

1、分析和定位策略

1、通過 show status 了解各種 SQL 的執行頻率

2、定位執行效率低的 SQL 語句:①通過慢日誌定位;②使用 show processlist 命令查看當前在進行的線程

3、通過 explain 分析低效 SQL

4、通過 show profile 分析 SQL

5、通過 trace 分析優化器的選擇

2、優化

1、大批量插入數據,使用如下方式能快速導入大量數據(在 myisam 引擎下速度更為顯著):

alter table 表名 disable keys; Loading the data

Alter table 表名 enable keys;

2、優化 insert 語句:

①對同一客戶插入很多行,盡量使用多個值表的 insert 語句,能大大縮減客戶端與數據庫之間的連接。例如 insert into 表名 values(1,2),(1,3),(1,4)····

②對不同客戶插入很多行,可以使用 insert delayed 語句更高速

③將索引文件和數據文件分在不同的磁盤上存放

④從一個文本文件裝載一個表時,使用 load data infile,速度會比 insert 快 20 倍左右

3、優化 order by 語句:

①mysql 中的兩種排序方式:第一種是有序索引順序掃描直接返回有序數據;第二種是

通過對返回數據進行排序(Filesort 排序)

②Filesort 優化:通過兩次掃描算法和一次掃描算法

4、優化 group by 語句:使用 group by null 可以避免用戶排序結果的消耗。

5、優化嵌套查詢:子查詢可以一次性完成多個步驟查詢,同時可以避免事務或者是表死鎖。

但是在有些情況下,連接查詢可以代替子查詢。

6、優化 or 條件:正確使用 or 條件查詢,當時在對有獨立索引的列查詢時 or 操作能夠快速

查找到結果;而在對有復合索引的列上做 or 操作時,卻不能用到索引

7、優化分頁查詢:

①思路一:在索引上完成排序分頁的操作,最後根據主鍵關聯回原表查詢所需要的其他列內容,這種方式讓 mysql 掃描盡可能少的頁面來提高分頁效率

②思路二:把 limit 查詢轉換成某個位置查詢。這樣把 limit m,n 轉換成 limit n 只適合在

排序字段不會出現重復值的環境下

8、使用 SQL 提示:

①use index:在查詢語句中表名的後面,添加 use index 來提供 mysql 去參考的索引列表,讓 mysql 不再去考慮其他索引

②ignore index:使用 ignore index 可以讓 mysql 忽略一個或者多個索引

③force index:強制 mysql 使用一個特定的索引,一定情況下可以避免全秒掃描

二.索引問題

1、索引的存儲分類

①B-Tree 索引:最常見的索引,大部分引擎都支持

②Hash 索引:只有 memory 引擎支持

③R-Tree 索引(空間索引):使用很少,只做了解

④Full-text(全文索引):主要用於全文索引,innodb mysql5.6 開始提供支持

2、Mysql 中使用索引的場景

①匹配全值:對索引中所有列都指定具體值,即對索引中的所有列都有等值匹配的條件

例:select * from rental where rental_date=’2017-06-27 17:40:59’ and customer_id=343;

②匹配值的範圍查詢:對索引的值能夠進行範圍查找

例:select * from rental where customer_id>=373 and customer_id<400;

③匹配最左前綴:僅僅使用索引中的最左邊列進行查找。

例:在 A+B+C 字段上的聯合索引能夠被 A、A+B、A+B+C 的等值查詢利用,但是不能被B、B+C 的等值查詢利用到。

④僅僅對索引進行查詢,檔查詢的列都在索引的字段中時,查詢的效率更高

⑤匹配列前綴:僅僅使用索引中的第一列,並且只包含索引第一列的開頭一部分進行查

⑥索引匹配部分精確而其他部分進行範圍匹配:

例:select a_id from rental where rental_date=’2006-02-14’ and customer_id >=300 and customer_id < 400

⑦如果列名是索引,那麽使用 column_name is null 就會使用索引

3、存在索引但不能使用索引的場景

①以%開頭的 Like 查詢不能夠利用索引

②數據類型出現隱式轉換的時候也不會使用索引,特別是當列類型是字符串,一定要在 where 條件中把字符串常量值用引號引起來,否則即便是有索引也是無效的

③復合索引的情況下,假如查詢條件不滿足最左原則,是不會使用索引的

④如果 mysql 估計使用索引比全表掃描更慢,則不使用索引

⑤用 or 分割開的條件,如果 or 前的條件中的列有索引,而後面的列中沒有索引,那麽涉及的索引都不會被用到

三、優化數據庫對象

1、優化表的數據類型:表需要使用何種數據類型是需要根據應用來判斷的。可以使用函數 procedure analyse()對當前應用的表進行分析,可以根據當前表提出優化建議

2、通過拆分提高表的訪問效率:

①垂直拆分:把主碼和一些列放到一個表,然後把主碼和另外的列放到另一個表中

②水平拆分:根據一列或多列的值把數據行放到兩個獨立的表中

3、使用中間表提高統計查詢速度:

①中間表復制源表部分數據,並且與源表相“隔離”,在中間表上做統計查詢不會對在 線用戶產生負面影響

②中間表上可以靈活地添加索引或者增加臨時用的新字段,從而達到提高統計查詢效率 和輔助統計查詢作用

四、鎖問題

1、MySQL 的 3 種鎖

①表(級)鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突概率最高, 並發度最低(MyISAM,鎖住整個表,可同時讀,不可寫)

②行(級)鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度小,發生鎖沖突概率最低,並 發度也最高(InnoDB,單獨的一行記錄加鎖)

③頁面鎖:開銷和加鎖時間介於表鎖和行鎖之間;會出現死鎖;鎖定粒度介於表鎖和行 鎖之間,並發度一般

2、MyISAM 的表級鎖

①兩種模式: 表共享讀鎖(所有用戶可以同時去讀同一個加了該表鎖的表,但是不能去對其進行 其他操作)

表獨占寫鎖(一個用戶在對加了該表鎖的表進行寫操作的時候,其他用戶不能對其 進行操作)。MyISAM 表的讀操作與寫操作之間,以及寫操作之間是串行的,只允許上述其 中一種操作進行

②加鎖:MyISAM 在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執 行更新操作(UPDATE、DELETE、INSERT 等)前,會自動給涉及的表加寫鎖,這個過程並不 需要用戶幹預,都是由 MyISAM 引擎自動完成加鎖

③MyISAM 鎖調度:MyISAM 存儲引擎的讀鎖和寫鎖是互斥的,讀寫操作是串行的。當 一個進程請求某個 MyISAM 表的讀鎖,同時另一個進程也請求同一表的寫鎖,此時 MySQL 會讓寫進程先獲得鎖。不僅如此,即使讀請求先到鎖等待隊列,寫請求後到,寫鎖也會插到 讀鎖請求之前

3、InnoDB 的鎖

①幾種鎖模式:

共享鎖(S 鎖):允許一個事務去讀一行,阻止其他事務獲得相同數據集的排他鎖

排它鎖(X 鎖):允許獲得排他鎖的事務更新數據,阻止其他事務取得相同數據集 的共享讀鎖和排他寫鎖。另外,為了允許行鎖和表鎖共存,實現多粒度鎖機制

意向共享鎖(IS 鎖):事務打算給數據行加行共享鎖,事務在給一個數據行加共享 鎖前必須先取得該表的IS 鎖。

意向排它鎖(IX 鎖):事務打算給數據行加行排他鎖,事務在給一個數據行加排他 鎖前必須先取得該表的 IX 鎖。

②加鎖方式:意向鎖是 InnoDB 自動加的,不需用戶幹預。對於 UPDATE、DELETE 和 INSERT 語句,InnoDB 會自動給涉及數據集加排他鎖(X);對於普通 SELECT 語句,InnoDB 不會加任何鎖

③在不通過索引條件查詢的時候,InnoDB 確實使用的是表鎖,而不是行鎖

④由於 MySQL 的行鎖是針對索引加的鎖,不是針對記錄加的鎖,所以雖然是訪問不同 行的記錄,但是如果是使用相同的索引鍵,是會出現鎖沖突 北京市昌平區建材城西路金燕龍辦公樓一層 電話:400-618-9090

⑤當表有多個索引的時候,不同的事務可以使用不同的索引鎖定不同的行,另外,不論 是使用主鍵索引、唯一索引或普通索引,InnoDB 都會使用行鎖來對數據加鎖。

4、鎖使用總結:

①表鎖更適合與以查詢為主,只有少量按索引條件更新數據的應用,如 Web 應用;

②行鎖更適合於有大量按索引條件並發更新少量不同數據,同時又有並發查詢的應用, 入一些在線事務處理;

五、應用優化

1.使用連接池

連接池:需要訪問數據庫的的地方,都已經預先創建好,可以直接獲取鏈接,分配給應用使 用,大大減少了創建新連接所耗費的資源。在訪問結束後,鏈接將重新交還給連接池,以供新訪問使用

2、減少對 mysql 的訪問

①避免對同一數據做重復檢索

②使用查詢緩存(query cache)

③增加 cache 層 PS:第③個和第②個作用差不多,只是 cache 層比 query cache 要更大,層次要深點,cache 層可以看做是 mysql 的二級數據庫,query cache 相當於 mysql 內部的緩存

3、負載均衡:是重用的一種優化方式,采用某種均衡算法,將固定的負載量分布到不同的 服務器上,以此來減輕單臺服務器的負載均衡,達到優化的目的

①利用 mysql 復制分流查詢操作:一個主服務器承擔更多操作,而多臺從服務器承擔產查詢 操作,主從之間通過復制實現數據的同步。多臺從服務器一方面用來確保可用性,一方面可 以創建不同的索引以滿足不同的查詢的需要。

②采用分布式數據庫架構:分布式的數據庫架構適合大數據量、負載高的情況,它具有良好 的擴展性和高可用性。(該情況只支持 innodb 存儲引擎)

4、其他優化措施

①對於沒有刪除行操作的 myisam 表,插入操作和查詢操作可以並行進行,因為沒有刪除操 作的表查詢期間不會阻塞插入操作

②充分利用列有默認值的事實,只有當插入的值不同於默認值時,才明確地插入值。這會減 少 mysql 需要做的語法分析從而提升插入速度

③表的字段盡量不使用自增長變量,在高並發的情況下該字段的自增長可能對效率有比較大的影響

概念補充

①更新丟失(Lost Update):當兩個或多個事務選擇同一行,然後基於最初選定的值更新該 行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題--最後的更新覆蓋 了由其他事務所做的更新。

②臟讀(Dirty Reads):一個事務正在對一條記錄做修改,在這個事務完成並提交前,這條 記錄的數據就處於不一致狀態;這時,另一個事務也來讀取同一條記錄,如果不加控制,第 二個事務讀取了這些“臟”數據,並據此做進一步的處理,就會產生未提交的數據依賴關系。 這種現象被形象地叫做"臟讀"。

③不可重復讀(Non-Repeatable Reads):一個事務在讀取某些數據後的某個時間,再次讀 取以前讀過的數據,卻發現其讀出的數據已經發生了改變、或某些記錄已經被刪除了!這種 現象就叫做“不可重復讀”。 北京市昌平區建材城西路金燕龍辦公樓一層 電話:400-618-9090

④幻讀(Phantom Reads):一個事務按相同的查詢條件重新讀取以前檢索過的數據,卻發 現其他事務插入了滿足其查詢條件的新數據,這種現象就稱為“幻讀”。

⑤死鎖(Deadlock):是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種 互相等待的現象,這些永遠在互相等待的進程稱為死鎖進程。表級鎖不會產生死鎖,所以解 決死鎖主要還是真對於最常用的 InnoDB。 PS:在讀取數據前,對其加鎖,阻止其他事務對數據進行修改可避免臟讀、不可重復讀、幻讀

⑥悲觀鎖(Pessimistic Lock):悲觀鎖的特點是先獲取鎖,再進行業務操作,即“悲觀”的 認為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進行業務操作

⑦樂觀鎖(Optimistic Lock):樂觀鎖的特點先進行業務操作,不到萬不得已不去拿鎖。即 “樂觀”的認為拿鎖多半是會成功的,因此在進行完業務操作需要實際更新數據的最後一步 再去拿一下鎖就好

⑧熱備份:熱備份是在數據庫運行的情況下,備份數據庫的方法。即熱備份是系統處於正常 運轉狀態下的備份

⑨冷備份:冷備份發生在數據庫已經正常關閉的情況下,當正常關閉時會提供一個完整的數 據庫。冷備份時將關鍵性文件拷貝到另外的位置的一種說法。冷備份是最快和最安全的方法。

mysql 優化擴展