讀書筆記-高性能MySQL中獲取的額外乾貨

MySQL邏輯架構

  • 最上層服務: 連接處理,授權認證,安全等
  • 第二層架構:包含了大多數的核心服務功能,包括:查詢解析、分析、優化、緩存、內置函數,所有跨存儲引擎的功能都在這一層實現,比如:存儲過程、觸發器、視圖等
  • 第三層架構:存儲引擎,負責MySQL的數據存儲和提取

  1. 讀寫鎖
  • 共享鎖/讀鎖
  • 排它鎖/寫鎖: 優先級高於讀鎖,一個寫請求可能會被插在讀鎖隊列前面
  1. 鎖粒度
  • 表鎖:alter table 之類語句會使用表鎖
  • 行級鎖

事務

隔離級別

  • READ UNCOMMITTED 未提交讀,事務中的未提交修改對其他事務可見,容易髒讀,一般不用
  • READ COMMITTED 提交讀/不可重複讀
  • REPEATABLE READ 可重複讀(MySQL默認事務隔離級別),引起幻讀(當某個事務在讀取範圍內數據時,另一事務在範圍內插入了新數據,某事務再次讀取時,會產生幻行),MVCC解決了幻讀的問題
  • SERIALIZABLE 可串行化 ,最高的隔離級別,

多版本併發控制 MVCC

  • MVCC只存在於可重複讀、提交讀兩個隔離級別下
  • 樂觀併發控制、悲觀併發控制
  • MVCC是通過在每行記錄後面保存兩個列來實現的(行的創建時間系統版本號,行的過期/刪除時間系統版本號),每開始一個新的事務,系統版本號就會遞增,事務的版本號就是該事務開始時刻的系統版本號。
  • 以InnoDB爲例:

    SELECT: 只查找版本號小於等於當前事務的數據行;行的刪除版本要麼未定義,要麼大於當前事務版本號。

    INSERT:爲新插入行保存當前系統版本號爲行版本號。

    DELETE:爲刪除行保存當前系統版本號爲行刪除標識。

    UPDATE:爲新插入行保存當前系統版本號爲行版本號,同時保存當前系統版本號爲原來行的行刪除標識。

還有啥

  1. 加快alter table 操作速度
  • 常見的alter方法都是新建空表,從舊錶中查出數據插入新表,然後廢除舊錶
  • 其實並不是所有的alter操作都會引起表重建。
  • 列的默認值存在表的.frm文件中,可以直接修改這個文件,這個語句會直接修改.frm文件而不涉及表數據
# 快速修改列默認值方法:
alter table film alter column end_time set default 5;
  • 修改表默認編碼方式
不推薦,只對新的字段生效,老的字段不會做改動
ALTER TABLE tb1 DEFAULT CHARACTER SET=utf8mb4 COLLATE utf8mb4_general_ci; 


不推薦,只單獨修改表裏面某個字段的字符集類型不推薦: 
ALTER TABLE tb1 change c c varchar(50) CHARACTER SET utf8mb4 not null default 'only for test' ;

推薦:這種寫法老的字段也修改成utf8mb4:
ALTER TABLE tb1 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  • 修改註釋

修改註釋實際只修改.frm文件,不會改動ibd文件的,操作執行的很快。

alter table tb_name modify `column_name` default null comment '編號***'

alter table tb_name comment '用戶表'
  • 分頁優化
常見的分頁寫法
select * from students limit 10000,20;  
# 這樣會將查出的10000行丟棄掉

優化:
可以取前一頁的最大行數的id,然後根據這個id來限制下一頁的起點。

例如:上一頁最大的id是87654321。sql可以採用如下的寫法:
select id,name from students where id> 87654321 limit 20
  1. MYSQL會在索引中儲存null值,Oracle不會
  2. MySQL限制了每個關聯操作最多只能有61張表,如果希望查詢快且併發性好,單個查詢最好在12個表以內做關聯
  3. 緩存表對優化搜索很有效,對於緩存表,可以使用不同的存儲引擎,比如MyISAM,會得到更小的索引佔用空間,還可以全文搜索。

索引

一般我們說的索引大多數指的是B-Tree 索引,B-Tree 索引意味着所有的值都是按照順序存儲的,且每一個葉子頁到根的距離相同,它之所以快,是因爲搜索是從索引的根節點開始搜索, 而在根節點的槽中存放了指向子節點的指針。

  • 此處有一張表
    索引爲 name, job_number, hired_time, 請暫時忽略索引的合理性,僅僅作爲聯合索引的講述
CREATE TABLE employe (
    name varchar(20) not null,
    job_number int not null,
    gender enum('m', 'f') not null,
    hired_time  date not null,
    key(name, job_number, hired_time)
)

B-Tree 適合的索引查找類型:

  1. 全值匹配

    比如: 搜索姓名Ann,工號爲123456,入職時間爲2018-11-11的員工
  2. 鍵值範圍查詢(由於索引列是順序組織起來的,所以特別適合範圍查找)

    比如:搜索姓在Anna和David之間的員工,此時只使用了索引的第一列name
  3. 鍵前綴查找(只適用於左前綴的查找)

    比如:搜索姓名爲Ann的員工或搜索姓名以A開頭的員工
  4. 全值匹配+範圍匹配

    比如:查詢姓名爲Ann,工號大於12345的員工

關於B-Tree的限制

  1. 如果不是按照索引列的最前綴開始查找,則無法使用索引

    比如:查找名字以a結尾的員工
  2. 不能跳過索引中的列

    比如:搜索名字爲Ann, 入職時間爲2018-01-01至今的員工,跳過了工號這一列,則索引實際只會使用第一列name或者hired_time,這個就看MYSQL內部的優化選擇了
  3. 如果查詢中涉及到某個列的範圍查詢,那剩餘右邊的列都無法使用索引優化查找

    比如:搜索姓名爲Ann,且工號在A12至C123之間的,入職時間爲2018-11-01的員工,此處工號爲範圍查詢,所以入職時間這一類無法使用索引查詢

其他

  1. 索引必須是獨立的列,不能是表達式/函數等
  2. 前綴索引能使索引更小、更快,缺點是不能做 order by 和 group by
  3. 當不需要考慮排序和分組時,選擇性高的列在前面是很好的
  4. 覆蓋索引:一個查詢的字段全是索引
  5. MySQL不能在索引中執行like操作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章