MySQL 开发日志 -- 性能调优
生活随笔
收集整理的這篇文章主要介紹了
MySQL 开发日志 -- 性能调优
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
* mysql> show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];選項解析:IN 'log_name' 指定要查詢的binlog文件名(不指定就是第一個binlog文件)FROM pos 指定從哪個pos起始點開始查起(不指定就是從整個文件首個pos點開始算)LIMIT [offset,] 偏移量(不指定就是0)row_count 查詢總條數(不指定就是所有行)* cmd里:mysqlbinlog --start-datetime="2021-06-11 17:30:00" --stop-datetime="2021-06-11 18:00:00" "C:\ProgramData\MySQL\MySQL Server 8.0\Data\SZ-XXJSZX-03179-bin.000002"** 給mysql的prompt也設置顏色在.bashrc中添加以下設置即可開啟顏色:alias mysql=$(echo -e 'mysql --prompt="\x1B[01;32m(\N)\x1B[0m \x1B[34m[\d]\x1B[0m> "')*《MySQL 性能調優與架構設計》《MySQL 數據庫性能優化之SQL優化》【目標:減少磁盤IO次數,降低CPU計算】1. 使用explain收集執行計劃2. 停掉聯網,整理服務器磁盤碎片【數據類型選擇】3.Double 少用,存儲長度大,精確性差4.Decimal不要用在固定精度的小數上,乘以固定倍數以整數存儲5.TinyInt/Int/BigInt 在數據量大時,建議嚴格區分使用,無負數時,加上unsigned6.text 處理性能低于 char, varchar7.char 用于定長字段,varchar 用于不定長,要設定合適的最大長度。8.date < timestamp < datetime (存儲空間), 不建議 int 代替 unix timestamp, 數據不直觀9.enum 用于存儲‘狀態字段’,省空間,易增改,不需要重建表數據set 用于存儲可預先定義的屬性數據,少空間,易操作10.LOB 類型數據不建議存入數據庫,存儲其指針。LOB, text, varchar超大字段,非要存表時最好拆分存儲在獨立表中。與常用數據隔開,使用常用數據每行數據量小,每頁存儲行數就增多,增加緩存命中率。11.latin1 用于純拉丁字符,無其它字符時不用 UTF8 或其它UNICODE字符,以節省空間【語句優化】12. minus,order by, group by, distinct 消耗CPU大戶, union, intersect 也是13. order by 可以省略的情況:知道索引已經 “排序” , 14. select * 少用, 當存在 order by 時會影響排序效率15. count(1), count(column) 有時并不比 count(*) 快16. join 代替 子查詢(Sub-Queries),避免在內存中創建臨時表17. or, in, not in少用, 盡量用 union, union all18. where name like "MySQL%" 用 where name >= "MySQL" and name < "MySQM"19. union 會進行結果集合的唯一性過濾,需要排序,如果確認結果不重復或不在乎重復,使用 union all20.update語句,只更改要求的字段,不要更改全部字段,否則會影響性能,產生大量日志。21. 類型轉換可能導致無法使用索引。對傳參進行轉換,不要對column字段轉換。22.優先優化高并發的SQL,而不是執行頻率低的某些‘大’SQL23.limit, top 用于分批處理數據,避免向客戶端返回大數據量while(1){mysql_query("delete from a where date <= '2021-06-21' limit 1000")if (mysql_affected_rows() == 0)) break;usleep(50000); //每次暫停一段時間,釋放表讓其他進程/線程訪問。}【系統功能】24.表變量 代替 臨時表DECLARE @temp table 代替 SELECT into #name from tablehttps://www.cnblogs.com/ericli-ericli/p/6826646.html數據庫大時,非要建臨時表,使用 select into #name 代替 create table #name,避免造成大量 log ,以提高速度。數據量不大(建議1000條內),則用 create table, 可以緩和系統表資源。25.游標(CURSOR)盡量避免使用游標,因為游標的效率較差。不建議10000條數據以上使用游標。26.基于集基于集的方法通常優于游標或臨時表。https://blog.csdn.net/weixin_39737757/article/details/11478672327.索引select快,insert、update、delete慢。一個表的索引不宜超過6個。索引不能包含NULL值的列,見【適度冗余】。復合索引,見【適度冗余】。短索引:如果一個列的前10或20個字符固定相同,可能指定前綴長度,使用短索引,提高查詢速度,節省空間和IO。避免頻繁更新聚集索引(主鍵索引)28.鎖表鎖:開銷小,鎖定粒度大,發生死鎖概率高,相對并發也低。行鎖:開銷大,鎖定粒度小,發生死鎖概率低,相對并發也高。表鎖:lock table ... unlock tables行鎖:共享鎖(S):select * from table_name where ... lock in share mode排他鎖(X):select * from table_name where ... for updatehttps://www.cnblogs.com/chenqionghe/p/4845693.html29.事務(transaction) 與鎖定表(1)事務默認鎖定數據庫,可以使用鎖定表的方式,緩解多用戶相互干擾:lock table table_name write selecct * from table_name where ......unlock tables(2)事務分為四種隔離級別:https://www.cnblogs.com/fjdingsd/p/5273008.html① Serializable (串行化):可避免臟讀、不可重復讀、幻讀的發生。② Repeatable read (可重復讀):可避免臟讀、不可重復讀的發生。③ Read committed (讀已提交):可避免臟讀的發生。④ Read uncommitted (讀未提交):最低級別,任何情況都無法保證。set [glogal | session] transaction isolation level 隔離級別名稱(如repeatable read);級別越高,數據越安全可靠,但系統性能越差。(3)避免大事務操作,提高系統并發能力。30.外鍵https://www.cnblogs.com/tearer/archive/2010/07/25/1784896.html適用性能要求不高,安全要求高的系統。能增強數據關聯性,保證數據一致性和完整性。select快,insert、update、delete慢。開發難度大。【適度冗余】 31.相同的column存儲在兩張不同的table中,減少需要通過join 2張(或更多)大表的方式來獲取獨立小字段.因為join的記錄很大,造成大量IO。同時設定column字段 not null, 確保更新時冗余字段也更新。雖然 MySQL null類型會進入索引,但如果是組合索引,null字段會影響整個索引效率。null在索引中的處理也會占用額外空間。32.Index 索引原則上用于數據量大、檢索需求大,更新頻率小的場景。Index 索引上避免:Index(column)使用null值,計算操作,數據類型轉換、使用函數、使用not、<>、!=、is null、is not null,33.聯合索引,也叫復合索引如index(name,age),1 where name = ? and age =? # 走組合索引2 where age =? and name = ? # 走組合索引3 where name = ? # 走組合索引4 where age =? # 不走組合索引,因為不是左前綴【參數優化】34.query_cache_size/query_cache_type(global)只適用于 select 語句,檢索需求大,更新頻率小的場景query_cache_size經驗大小256M,通過計算命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100)調整大小,query_cache_type:0(OFF) :完全不用1(ON) :除顯式要求不用(sql_no_cache)之外,其它select都使用query_cache2(DEMOND):只有顯式需要使用(sql_cache)時才用35.query_cache_limit = 1M查詢緩存限制,只有1M以下查詢結果才會被緩存,以免結果數據較大把緩存池覆蓋36.binlog_cache_size(global):binlog cache是短時間內臨時緩存二進制日志數據的內存區域。數據庫無大事務,寫入也不頻繁時,大小2~4MB為合適。建議最大也不要超過32MB.可通過 binlog_cache_use、binlog_cache_disk_use 分析 size 是否足夠。查看其它參數:show variables like '%binlog%';https://www.jianshu.com/p/16b085c55e9637.key_buffer_size(global): 僅用于設置MyISAM存儲引擎中索引文件的內存區域大小。內存足夠時,確保該區域能存放下所有MyISAM引擎表的所有索引.建議16MB以內。38.read_buffer_size讀操作緩沖區大小,推薦設置16M或32M39.bulk_insert_buffer_size(thread):僅用于MyISAM,,用來緩存批量插入數據的時候臨時緩存寫入數據。一般8M,數據量大建議16~32MB,場景:insert ... select ...insert ... values (...), (...), (...) ...load data infile ... into ... (非空表)40.innodb_change_buffering:innodb_change_buffer_max_size:非聚集索引的插入(更新、刪除、徹底刪除)等操作,若不存在緩沖池上,則先存放到Insert(update、delete、Purge)buffer對象中,然后以一定頻率使Insert(update、elete、Purge)buffer 和非聚集索引葉子結點合并。通常是多個寫入操作合并到一個 操作中,使用葉子節點存儲的數據不會過于離散、比較有順序,減少隨機讀取的操作。參數值:默認是all,表示啟動所有。此外還有inserts,deletes,purges,changes,none;changes表示啟用inserts和deletes;none表示都不啟用。innodb_change_buffer_max_size=25表示最多使用25%緩沖池空間,最大為5041.innodb_buffer_pool_size(global):設置用于緩存innodb索引及數據塊的存在區域大小計算緩存命中率以調整size:(Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100%42.innodb_buffer_pool_instances:InnoDB支持多個緩沖池實例,每個頁根據不同的哈希值分配到不同的緩沖池當中。好處是減少數據庫內部的資源競爭,增加數據庫的并發能力。這個參數似乎沒法修改,根據服務器的核數設置。43.innodb_additional_mem_pool_size(global):設置用來存放數據字典信息及內部數據結構的內存空間大小當該值過小時,會記錄warning信息到error log中。建議8~16MB,表特別多時32MB。44.innodb_log_buffer_size(global):存儲引擎事務日志的緩沖區大小默認1MB,系統繁忙時4~8MB.在寫事務日志時,先寫入innodb log bufferkh ,當滿足innodb_flush_log_trx_commit的條件或緩沖區寫滿時,才將日志寫到文件(或者同步到磁盤)中。 45.innodb_flush_log_at_trx_commit:0:log buffer中的數據以每秒一次的頻率寫入到log file, 且同時會進行文件系統到磁盤的同步操作,每個事務的commit不會觸發任何log buffer到log file的刷新或者觸發文件系統到磁盤的同步操作。1: 每個事務的commit時會觸發當前log buffer到log file的刷新并且觸發文件系統到磁盤的同步操作。2:每個事務的commit時會觸發當前log buffer到log file的刷新但不觸發文件系統到磁盤的同步操作,每秒會有一次文件系統到磁盤的同步操作。46.innodb_max_dirty_pages_pct(global):在innodb buffer pool中可以不用寫入數據文件中的dirty page的比例。比例值超大,從內存到磁盤的寫入操作就越少。如果比例值過大,當數據庫crash后重啟的時間就會很長,因為有大量的事務數據需要從日志文件恢復出來寫入數據文件中。同時,可能造成在達到比例設定的上限后的flush操作“過猛”而導致性能波動很大。 重啟恢復的數據如果超過1GB,啟動速度會比較慢,建議這個值不大于 1GB/innodb_buffer_pool_size(GB)*100,即不要超過90.47.innodb_file_per_table = OFF默認是共享表空間,共享表空間idbdata文件不斷增大,影響一定的I/O性能。推薦開啟獨立表空間模式,每個表的索引和數據都存在自己獨立的表空間中,可以實現單表在不同數據庫中移動。48.LRU len 和 unzip_LRU:innodb支持壓縮頁的功能,將原本16k的頁壓縮為1k、2k、4k、8k等。由于大小的變化,對于頁的管理也發生了變化。經過壓縮的頁由unzip_LRU管理。其中LRU len當中是包含了unzip_LRU的數量的。使用命令查看:show engine innodb status\G;49.innodb_use_native_aio: AIO(Async IO), 異常IO訪問開關,異步速度快,可合并連續頁訪問的多個IO為一個整體的IO請求。50.innodb_flush_neighbors:刷新鄰接頁(Flush Neighbor Page),刷新一個臟頁時,InnoDB會檢測該頁所在區的所有頁,如果是臟頁,那么一起刷新到磁盤。傳統機械硬盤建議開啟,固態硬盤建議關閉,即值設為0;51.slow_query_log:慢日志查詢開關開啟: set global slow_query_log=on;long_query_time:慢日志執行時間閾值log_queries_not_using_indexes:設置慢查詢日志是否記錄不使用索引的查詢可用于定位數據庫中較慢的查詢語句。52.Cardinality該值表示索引中不重復記錄數量的預估值,反映了索引對整表數據的覆蓋率。cardinality/n_rows_in_table應盡可能的接近1。如果該值非常小,則沒有建立該索引的必要。查詢方式:show index from your_db.your_table_name;https://www.jianshu.com/p/ba6248a7abdf53.MRR(Mutil-Range Read)MRR 通過把「隨機磁盤讀」,轉化為「順序磁盤讀」,從而提高了索引查詢的性能。在查詢輔助索引時,首先根據得到的查詢結果,按照主鍵進行排序,并按照主鍵排序的順序進行書簽查找。#開啟mrrset optimizer_switch='mrr=on';#基于成本的邏輯判斷開關,開啟的話mysql會判斷是否需要使用mrrset optimizer_switch='mrr_cost_based=on'; 54.max_connections同時處理最大連接數,推薦設置最大連接數是上限連接數的85%左右https://www.cnblogs.com/phpper/p/9570792.html55.sort_buffer_size = 2M查詢排序時緩沖區大小,只對order by和group by起作用,可增大此值為16M56.open_files_limit = 1024打開文件數限制,如果show global status like 'open_files'查看的值等于或者大于open_files_limit值時,程序會無法連接數據庫或卡死【性能指標】57.QPS(Queries Per Second): 每秒查詢數,一臺數據庫每秒能夠處理的查詢次數QPS = Questions / UptimeQPS = Com_select(1s) + Com_insert(1s) + Com_delete(1s) + Com_update(1s)58.TPS,Transactions Per Second:每秒處理事務數TPS = (Com_commit + Com_rollback) / Uptime【分區】查詢是否開啟分區功能:mysql5.6: show variables like '%partition%';mysql8:select table_schema, table_name, partition_name,partition_method,partition_expression from information_schema.PARTITIONS where table_name = 'your_table_name';橫向分區:按行分區,若干行分在一個區。縱向分區:也叫分表,把大字段分到一個獨立表中。mysql支持橫向分區,細分為幾種分區類型:https://www.cnblogs.com/lonnie/p/10681512.html1)RANGE分區:行數據屬于一個給定的連續列值的范圍,責備加入該分區。2)LIST分區:和RANGE分區類型相比,只是LIST分區面向離散的值。如取奇遇值分到兩個區。3)HASH分區:根據用戶自定義的返回值來確定分區,返回值不能為負數。4)KEY分區:根據mysq提供的hash函數進行分區。子分區:是分區表中每個分區的再次分割,子分區既可以使用HASH希分區,也可以使用KEY分區。這也被稱為復合分區(composite partitioning)。分區的性能數據庫分為OLTP(在線事務處理應用)和OLAP(在線分析應用)。對于OLAP,可以很好的提升性能。比如有一張上億的表,用戶需要根據某些列不斷的查詢。如果我們以時間段對表做分區,則只需要查詢該分區的表數據。對于OLTP,分區要相對小心。通常很少有需要獲取超過表中10%數據的要求,而對于只需要獲取幾條甚至單條數據的請求,B+樹的兩到三次的IO能夠很好的完成操作。并不需要分區方式。相反,設計不好,會帶來嚴重的性能問題。【分表】https://www.cnblogs.com/lonnie/p/10681512.htmlhttps://www.cnblogs.com/shiliuye/p/13099256.html1.利用集群cluster,proxy,replication,drdb等等2.預先估計會出現的大數據并且訪問頻繁的表,將其分為若干個表.用hash,求余等方式分派數據到各表中。3.利用merge存儲引擎來實現分表4.垂直分表: 把原來有很多列的表拆分成多個表,原則是:(1)把常用、不常用的字段分開放(2)把大字段獨立存放在一個表中5.水平分表:(1)按時間(2)按版塊(新聞、體育、娛樂。。。)(3)哈希分表(博客)【自動優化】* CheckPoint技術:https://www.jianshu.com/p/9d824138bbef* 自適應哈希索引(Adaptive Hash Index)https://www.jianshu.com/p/b8df618b90e2* ICP(Index Condition Pushdown,索引下推)本來組合索引Index(a,b,c)就應該具備Index(a,b)、Index(a,c)、Inde(b,c)的能力。但mysql5.6前并無此能力。如: select *from table1 where a=xx and b=xx以前是無法使用Index(a,b,c),有了ICP技術使得使用Index(a,b,c)的a部分的同時,也使用b(或c)進行過濾。這個過程在index filter階段完成,而不用到table filter(回表)階段再進行。https://www.jianshu.com/p/ba6248a7abdfhttps://www.cnblogs.com/digdeep/p/4994130.html【五種范式】* 范式比較適用于Oracle, 對于MySQL要求不并高,有時不適用。【內核優化】* 大多數MySQL都部署在linux系統上,所以操作系統的一些參數也會影響到MySQL性能,以下對linux內核進行適當優化。1.net.ipv4.tcp_fin_timeout = 30#TIME_WAIT超時時間,默認是60s2.net.ipv4.tcp_tw_reuse = 1 #1表示開啟復用,允許TIME_WAIT socket重新用于新的TCP連接,0表示關閉3.net.ipv4.tcp_tw_recycle = 1 #1表示開啟TIME_WAIT socket快速回收,0表示關閉4.net.ipv4.tcp_max_tw_buckets = 4096 #系統保持TIME_WAIT socket最大數量,如果超出這個數,系統將隨機清除一些TIME_WAIT并打印警告信息5.net.ipv4.tcp_max_syn_backlog = 4096#進入SYN隊列最大長度,加大隊列長度可容納更多的等待連接6.file fd(文件句柄數)系統默認1024。當提示“too many files open”時,修改# vi /etc/security/limits.conf #加入以下配置,*代表所有用戶,也可以指定用戶,重啟系統生效* soft nofile 65535* hard nofile 65535# ulimit -SHn 65535 #立刻生效7.mpstat -P ALL 1 1000查看CPU性能,1秒內對所有cpu采樣1000次,統計使用狀態。8.iostat -m -x 1 1000查看I/O性能,以M為單位,默認是K,每1秒采樣1000次,顯示擴展信息【集群】1.主從架構,雙機熱備(Keepalived、Heartbeat),多機負載均衡有LVA、HAProxy、Nginxhttp://lizhenliang.blog.51cto.com/7876557/13623132.主從復制管理工具,MySQL-MMM(Master-Master replication managerfor Mysql,Mysql主主復制管理器)3.MySQL Proxy,Amoeba等代理程序,實現讀寫分享。4.分布式緩存:memcached、redis。*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
?
總結
以上是生活随笔為你收集整理的MySQL 开发日志 -- 性能调优的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【MFC】选择文件夹时,记忆上一次路径
- 下一篇: X86汇编——字符串逆序输出