簡單來說在高并發情況下當前讀是獲取最新的記錄并且其他事務不能修改這個記錄、快照讀獲取的有可能是老的數據。當前讀是加了鎖的,并且加的是悲觀鎖。而快照讀是沒加鎖的。
MVCC,全稱Multi-Version Concurrency Control,即多版本并發控制,是一種高并發版本控制器,一般用于數據庫中對數據的并發訪問。Mysql中的innoDB中就是使用這種方法來提高讀寫事務的并發性能。因為MVCC是一種不采用鎖來控制事務的方式,是一種非堵塞、同時還可以解決臟讀,不可重復讀,幻讀等事務隔離問題,但不能解決更新丟失問題。
總之:就是MVCC是通過保存數據的歷史版本,根據比較版本號來處理數據是否顯示,從而達到讀取數據的時候不需要加鎖就可以保證事務隔離性的效果。
MVCC的實現原理是依靠記錄中的3個隱含字段、undo log日志(回滾日志 )、Read View來實現的。
1:隱含字段:
DB_TRX_ID:記錄操作該數據事務的事務id;
DB_ROLL_PTR:指向上一個版本數據在undo log里的位置指針
DB_ROW_ID:隱藏ID,當創建表沒有合適的索引作為聚集索引時,會用該隱藏ID創建聚集索引
2:undo log日志:
insert undo log:在進行插入操作事務時產生、在事務回滾時需要、在提交事務后可以被立即丟掉
update undo log:進行update、delete時產生的undo log、不僅在回滾事務時需要、在快照讀時也需要。所以不能隨便刪除,只有在快照讀或事務回滾不涉及該日志時,對應的日志才會被purge線程統一清除(purge類似jvm中的gc垃圾回收器)
3:Read View(讀視圖)
Read View讀視圖就是用來記錄發生快照讀那一刻所有的記錄,當你下次就算有執行新的事務記錄改變了,read view沒變,讀出來的數據依然是不變的。
而隔離級別中的RR(可重復讀)、和RC(提交讀)不同就是差在快照讀時。前者創建一個快照和Read View,并且下次快照讀時使用的還是同一個Read View,所以其他事務修改數據對他是不可見的、解決了不可重復讀問題。后者則是每次快照讀時都會產生新的快照和Read View所以就會產生不可重復讀問題。
MySQL 數據庫中有六種觸發器:
● Before Insert、After Insert
● Before Update、After Update
● Before Delete、After Delete
開啟Mysql的查詢緩存,當執行完全相同的SQL語句的時候,服務器就會直接從緩存中讀取結果,當數據被修改,之前的緩存會失效,修改比較頻繁的表不適合做查詢緩存。
1. 查看當前的MySQL數據庫是否支持查詢緩存:
SHOW VARIABLES LIKE 'have_query_cache';
2. 查看當前MySQL是否開啟了查詢緩存 :
SHOW VARIABLES LIKE 'query_cache_type';
3. 查看查詢緩存的占用大小 :
SHOW VARIABLES LIKE 'query_cache_size';
4. 查看查詢緩存的狀態變量:
SHOW STATUS LIKE 'Qcache%';
1) SQL 語句不一致的情況, 要想命中查詢緩存,查詢的SQL語句必須完全一致。
select count(*) from tb_item; SQL2 : Select count(*) from tb_item;
2) 當查詢語句中有一些不確定的時,則不會緩存。如 : now() , current_date() , curdate() , curtime() , rand() ,uuid() , user() , database() 。
select * from tb_item where updatetime < now() limit 1;?
select user();?
select database();
3) 不使用任何表查詢語句。
select 'A';
4) 查詢 mysql, information_schema或 performance_schema 數據庫中的表時,不會走查詢緩存。
select * from information_schema.engines;
5) 在存儲的函數,觸發器或事件的主體內執行的查詢。
6) 如果表更改,則使用該表的所有高速緩存查詢都將變為無效并從高速緩存中刪除。這包括使用 MERGE 映射到已更改表的表的查詢。一個表可以被許多類型的語句,如被改變 INSERT, UPDATE, DELETE,TRUNCATE TABLE, ALTER TABLE, DROP TABLE,或 DROP DATABASE 。
● 盡量用小范圍的數據類型:一般情況下,應該盡量使用可以正確存儲數據的最小范圍數據類型。
● 盡量用整型:簡單的數據類型通常需要更少的CPU周期。例如,整數比字符操作代價更低,因為字符集和校對規則(排序規則)使字符比較比整型比較復雜。
● 盡量避免NULL:通常情況下最好指定列為NOT NULL 。
最好是按照以下順序優化:
1.SQL語句及索引的優化
2. 數據庫表結構的優化
3.系統配置的優化
4.硬件的優化