1. 程式人生 > >mysql數據庫優化一

mysql數據庫優化一

CP 函數 發送數據 schema 單獨 nbsp join post sch

首先看下mysql數據庫發送和接受請求的整個流程

技術分享圖片

MySQL邏輯架構整體分為三層,最上層為客戶端層,並非MySQL所獨有,諸如:連接處理、授權認證、安全等功能均在這一層處理。

MySQL大多數核心服務均在中間這一層,包括查詢解析、分析、優化、緩存、內置函數(比如:時間、數學、加密等函數)。所有的跨存儲引擎的功能也在這一層實現:存儲過程、觸發器、視圖等。

最下層為存儲引擎,其負責MySQL中的數據存儲和提取。和Linux下的文件系統類似,每種存儲引擎都有其優勢和劣勢。中間的服務層通過API與存儲引擎通信,這些API接口屏蔽了不同存儲引擎間的差異。

技術分享圖片

客戶端/服務端通信協議

MySQL客戶端/服務端通信協議是“半雙工”的:在任一時刻,要麽是服務器向客戶端發送數據,要麽是客戶端向服務器發送數據,這兩個動作不能同時發生。一旦一端開始發送消息,另一端要接收完整個消息才能響應它,所以我們無法也無須將一個消息切成小塊獨立發送,也沒有辦法進行流量控制。

客戶端用一個單獨的數據包將查詢請求發送給服務器,所以當查詢語句很長的時候,需要設置max_allowed_packet參數。但是需要註意的是,如果查詢實在是太大,服務端會拒絕接收更多數據並拋出異常。

與之相反的是,服務器響應給用戶的數據通常會很多,由多個數據包組成。但是當服務器響應客戶端請求時,客戶端必須完整的接收整個返回結果,而不能簡單的只取前面幾條結果,然後讓服務器停止發送。因而在實際開發中,盡量保持查詢簡單且只返回必需的數據,減小通信間數據包的大小和數量是一個非常好的習慣,這也是查詢中盡量避免使用SELECT *以及加上LIMIT限制的原因之一。

MySQL使用基於成本的優化器 在MySQL可以通過查詢當前會話的last_query_cost的值來得到其計算當前查詢的成本。

大表ALTER TABLE非常耗時,MySQL執行大部分修改表結果操作的方法是用新的結構創建一個張空表,從舊表中查出所有的數據插入新表,然後再刪除舊表。

schema的列不要太多。原因是存儲引擎的API工作時需要在服務器層和存儲引擎層之間通過行緩沖格式拷貝數據,然後在服務器層將緩沖內容解碼成各個列,這個轉換過程的代價是非常高的。如果列太多而實際使用的列又很少的話,有可能會導致CPU占用過高。

添加索引的時間肯定是遠大於初始添加索引所需要的時間


[inner] join on/using
如果兩個表的關聯字段名是一樣的,就可以使用Using來建立關系,簡潔明了。如果不一樣,只能用On了哦~

分頁和where語句

select * from reader where id>5000;
select * from reader limit 5000,10;
分頁會先將記錄全部排序一遍,選取5000以後的十條數據量,而where條件表達式逐條查詢,大於5000就抽出來,不需要先排序。


SELECT film_id,description FROM film ORDER BY title LIMIT 50,5;
當LIMIT的偏移量特別大的時候,就要采用分組來減少掃描的頁面
讓MySQL掃描盡可能少的頁面,獲取需要訪問的記錄後在根據關聯列回原表查詢所需要的列
SELECT film.film_id,film.description
FROM film INNER JOIN (
SELECT film_id FROM film ORDER BY title LIMIT 50,5
) AS tmp USING(film_id);

具體的描述參考以下鏈接:

https://www.jianshu.com/p/d7665192aaaf

mysql數據庫優化一