一、導(dǎo)致SQL慢的原因
(1)硬件問題:網(wǎng)絡(luò)慢,IO慢,內(nèi)存不足,吞吐量小,磁盤空間滿
(2)Sql寫法問題
(3)數(shù)據(jù)過多,分庫(kù)分表
(4)索引失效
(5)服務(wù)器調(diào)優(yōu)及各個(gè)參數(shù)設(shè)置
二、分析原因時(shí),一定要找切入點(diǎn)
(1)先觀察,開啟慢查詢?nèi)罩?,設(shè)置相應(yīng)的閾值(比如超過3秒就是慢SQL),在生產(chǎn)環(huán)境跑上個(gè)一天過后,看看哪些SQL比較慢。
(2)Explain和慢SQL分析。比如SQL語(yǔ)句寫的爛,索引沒有或失效,關(guān)聯(lián)查詢太多(有時(shí)候是設(shè)計(jì)缺陷或者不得以的需求)等等。
(3)Show Profile是比Explain更近一步的執(zhí)行細(xì)節(jié),可以查詢到執(zhí)行每一個(gè)SQL都干了什么事,這些事分別花了多少秒。
(4)找DBA或者運(yùn)維對(duì)MySQL進(jìn)行服務(wù)器的參數(shù)調(diào)優(yōu)。
三、優(yōu)化之sql語(yǔ)法
3.1建表字段
(1)盡量使用TINYINT、SMALLINT、MEDIUM_INT
作為整數(shù)類型而非INT,如果非負(fù)則加上UNSIGNED;
(2)VARCHAR的長(zhǎng)度只分配真正需要的空間;
(3)使用枚舉或整數(shù)代替字符串類型;
(4)盡量使用TIMESTAMP而非DATETIME;
(5)單表不要有太多字段,建議在20以內(nèi);
(6)避免使用NULL字段,很難查詢優(yōu)化且占用額外索引空間;
(7)用整型來存IP。
(8)把字符轉(zhuǎn)化為數(shù)字
(9)優(yōu)先使用Enum或Set
(10)避免使用Null字段
(11)少用并拆封Text/Blob
(12)不在數(shù)據(jù)庫(kù)中存圖片
3.2建表索引
(1)索引并不是越多越好,要根據(jù)查詢有針對(duì)性的創(chuàng)建,考慮在WHERE和ORDER BY命令上涉及的列建立索引,可根據(jù)EXPLAIN來查看是否用了索引還是全表掃描;
(2)應(yīng)盡量避免在WHERE子句中對(duì)字段進(jìn)行NULL值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描;
(3)值分布很稀少的字段不適合建索引,例如"性別" 這種只有兩三個(gè)值的字段;
(4)字符字段只建前綴索引;
(5)字符字段最好不要做主鍵;
(6)不用外鍵,由程序保證約束;
(7)盡量不用UNIQUE,由程序保證約束;
(8)使用多列索引時(shí)主意順序和查詢條件保持一致,同時(shí)刪除不必要的單列索引。
3.3 查詢SQL
(1)可通過開啟慢查詢?nèi)罩緛碚页鲚^慢的SQL;
(2)不做列運(yùn)算:SELECT id WHERE age + 1 = 10,任何對(duì)列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫(kù)教程函數(shù)、計(jì)算表達(dá)式等等,查詢時(shí)要盡可能將操作移至等號(hào)右邊;
(3)SQL語(yǔ)句盡可能簡(jiǎn)單:一條?SQL?只能在一個(gè) CPU 運(yùn)算;大語(yǔ)句拆小語(yǔ)句,減少鎖時(shí)間;一條大?SQL?可以堵死整個(gè)庫(kù);
(4)不用SELECT *;
(5)OR改寫成IN:OR的效率是 n 級(jí)別,IN的效率是 log(n) 級(jí)別,in 的個(gè)數(shù)建議控制在 200 以內(nèi);
(6)不用函數(shù)和觸發(fā)器,在應(yīng)用程序?qū)崿F(xiàn);
(7)避免%xxx式查詢;
(8)少用JOIN;
(9)使用同類型進(jìn)行比較
(10)盡量避免在WHERE子句中使用!= 或 <> 操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描;
(11)對(duì)于連續(xù)數(shù)值,使用BETWEEN不用IN:
(12)列表數(shù)據(jù)不要拿全表,要使用LIMIT來分頁(yè),每頁(yè)數(shù)量也不要太大。
SQL編寫時(shí)還需要特別注意一下幾點(diǎn):
(1)盡量規(guī)避大事務(wù)的SQL,大事務(wù)的 SQL 會(huì)影響數(shù)據(jù)庫(kù)的并發(fā)性能及主從同步;
(2)分頁(yè)語(yǔ)句limit的問題;
(3)刪除表所有記錄請(qǐng)用truncate,不要用 delete;
(4)不讓mysql干多余的事情,如計(jì)算;
(5)輸寫SQL帶字段,以防止后面表變更帶來的問題,性能也是比較優(yōu)的 ( 涉及到數(shù)據(jù)字典解析,請(qǐng)自行查詢資料);
(7)慎用Oder by rand()。
3.4 常見SQL優(yōu)化
(1)LIMIT語(yǔ)句:分頁(yè)limit 1000,10 會(huì)耗時(shí)
(2)隱式轉(zhuǎn)換
(3)關(guān)聯(lián)更新、刪除
原語(yǔ)句:UPDATE operation o SET ???status = 'applying' WHERE ?o.id IN
????(SELECT id FROM ??(SELECT o.id, ?o.status FROM ??operation o ?WHERE ?o.group = 123 AND o.status NOT IN ( 'done' ) ORDER ?BY o.parent LIMIT ?1) t);
優(yōu)化后語(yǔ)句:
UPDATE operation o JOIN ?(SELECT o.id, ?o.status FROM ??operation o WHERE ?o.group = 123 ??AND o.status NOT IN ( 'done' ) ORDER ?BY o.parent LIMIT ?1) t
?????ON o.id = t.id SET ???status = 'applying'
(4)EXISTS語(yǔ)句:去掉 exists 更改為 join,能夠避免嵌套子查詢
四、優(yōu)化之sql數(shù)據(jù)庫(kù)
4.1 系統(tǒng)調(diào)優(yōu)參數(shù)
可以使用下面幾個(gè)工具來做基準(zhǔn)測(cè)試:
sysbench:
一個(gè)模塊化,跨平臺(tái)以及多線程的性能測(cè)試工具;
iibench-mysql:
基于Java的MySQL/Percona/MariaDB 索引進(jìn)行插入性能測(cè)試工具;
tpcc-mysql:
Percona開發(fā)的 TPC-C 測(cè)試工具。
具體的調(diào)優(yōu)參數(shù)內(nèi)容較多,具體可參考官方文檔,這里介紹一些比較重要的參數(shù):
(1)back_log:back_log 值指出在 MySQL暫時(shí)停止回答新請(qǐng)求之前的短時(shí)間內(nèi)多少個(gè)請(qǐng)求可以被存在堆棧中。也就是說,如果MySql的連接數(shù)據(jù)達(dá)到max_connections 時(shí),新來的請(qǐng)求將會(huì)被存在堆棧中,以等待某一連接釋放資源,該堆棧的數(shù)量即 back_log,如果等待連接的數(shù)量超過 back_log,將不被授予連接資源??梢詮哪J(rèn)的50升至 500;
(2)wait_timeout:數(shù)據(jù)庫(kù)連接閑置時(shí)間,閑置連接會(huì)占用內(nèi)存資源??梢詮哪J(rèn)的 8 小時(shí)減到半小時(shí);
(3)max_user_connection:最大連接數(shù),默認(rèn)為0無上限,最好設(shè)一個(gè)合理上限;
(4)thread_concurrency:并發(fā)線程數(shù),設(shè)為 CPU 核數(shù)的兩倍;
(5)skip_name_resolve:禁止對(duì)外部連接進(jìn)行 DNS 解析,消除 DNS 解析時(shí)間,但需要所有遠(yuǎn)程主機(jī)用 IP 訪問;
(6)key_buffer_size:索引塊的緩存大小,增加會(huì)提升索引處理速度,對(duì) MyISAM 表性能影響最大。對(duì)于內(nèi)存4G左右,可設(shè)為256M或384M,通過查詢show status like 'key_read%',保證key_reads / key_read_requests在 0.1% 以下最好;
(7)innodb_buffer_pool_size:緩存數(shù)據(jù)塊和索引塊,對(duì) InnoDB 表性能影響最大。通過查詢show status like 'Innodb_buffer_pool_read%',保證?(Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests越高越好;
(8)innodb_additional_mem_pool_size:
InnoDB存儲(chǔ)引擎用來存放數(shù)據(jù)字典信息以及一些內(nèi)部數(shù)據(jù)結(jié)構(gòu)的內(nèi)存空間大小,當(dāng)數(shù)據(jù)庫(kù)對(duì)象非常多的時(shí)候,適當(dāng)調(diào)整該參數(shù)的大小以確保所有數(shù)據(jù)都能存放在內(nèi)存中提高訪問效率,當(dāng)過小的時(shí)候,MySQL 會(huì)記錄 Warning 信息到數(shù)據(jù)庫(kù)的錯(cuò)誤日志中,這時(shí)就需要該調(diào)整這個(gè)參數(shù)大?。?/p>
(9)innodb_log_buffer_size:InnoDB 存儲(chǔ)引擎的事務(wù)日志所使用的緩沖區(qū),一般來說不建議超過 32MB;
(10)query_cache_size:緩存 MySQL 中的 ResultSet,也就是一條 SQL 語(yǔ)句執(zhí)行的結(jié)果集,所以僅僅只能針對(duì) select 語(yǔ)句。當(dāng)某個(gè)表的數(shù)據(jù)有任何任何變化,都會(huì)導(dǎo)致所有引用了該表的 select 語(yǔ)句在 Query Cache 中的緩存數(shù)據(jù)失效。所以,當(dāng)我們的數(shù)據(jù)變化非常頻繁的情況下,使用 Query Cache 可能會(huì)得不償失。
根據(jù)命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))進(jìn)行調(diào)整,一般不建議太大,256MB 可能已經(jīng)差不多了,大型的配置型靜態(tài)數(shù)據(jù)可適當(dāng)調(diào)大。可以通過命令show status like 'Qcache_%'查看目前系統(tǒng) Query catch 使用大??;
(11)read_buffer_size:MySql 讀入緩沖區(qū)大小。對(duì)表進(jìn)行順序掃描的請(qǐng)求將分配一個(gè)讀入緩沖區(qū),MySql 會(huì)為它分配一段內(nèi)存緩沖區(qū)。如果對(duì)表的順序掃描請(qǐng)求非常頻繁,可以通過增加該變量值以及內(nèi)存緩沖區(qū)大小提高其性能;
(12)sort_buffer_size:MySql 執(zhí)行排序使用的緩沖大小。如果想要增加ORDER BY的速度,首先看是否可以讓 MySQL 使用索引而不是額外的排序階段。如果不能,可以嘗試增加 sort_buffer_size 變量的大?。?/p>
(13)read_rnd_buffer_size:MySql 的隨機(jī)讀緩沖區(qū)大小。當(dāng)按任意順序讀取行時(shí) (例如,按照排序順序),將分配一個(gè)隨機(jī)讀緩存區(qū)。進(jìn)行排序查詢時(shí),MySql 會(huì)首先掃描一遍該緩沖,以避免磁盤搜索,提高查詢速度,如果需要排序大量數(shù)據(jù),可適當(dāng)調(diào)高該值。但 MySql 會(huì)為每個(gè)客戶連接發(fā)放該緩沖空間,所以應(yīng)盡量適當(dāng)設(shè)置該值,以避免內(nèi)存開銷過大;
(14)record_buffer:每個(gè)進(jìn)行一個(gè)順序掃描的線程為其掃描的每張表分配這個(gè)大小的一個(gè)緩沖區(qū)。如果你做很多順序掃描,可能想要增加該值;
(15)thread_cache_size:保存當(dāng)前沒有與連接關(guān)聯(lián)但是準(zhǔn)備為后面新的連接服務(wù)的線程,可以快速響應(yīng)連接的線程請(qǐng)求而無需創(chuàng)建新的;
(16)table_cache:類似于 thread_cache_size,但用來緩存表文件,對(duì) InnoDB 效果不大,主要用于 MyISAM。
4.2 升級(jí)硬件
Scale up,這個(gè)不多說了,根據(jù) MySQL 是 CPU 密集型還是 I/O 密集型,通過提升 CPU 和內(nèi)存、使用 SSD,都能顯著提升 MySQL 性能。
五、優(yōu)化之讀寫分離
也是目前常用的優(yōu)化,從庫(kù)讀主庫(kù)寫,一般不要采用雙主或多主引入很多復(fù)雜性,盡量采用文中的其他方案來提高性能。同時(shí)目前很多拆分的解決方案同時(shí)也兼顧考慮了讀寫分離。
讀寫分離的實(shí)現(xiàn)原理就是在執(zhí)行SQL語(yǔ)句的時(shí)候,判斷到底是讀操作還是寫操作,把讀的操作轉(zhuǎn)向到讀服務(wù)器上(從服務(wù)器,一般是多臺(tái)),寫的操作轉(zhuǎn)到寫的服務(wù)器上(主服務(wù)器,一般是一臺(tái),視數(shù)據(jù)量來看)。
當(dāng)然為了保證多臺(tái)數(shù)據(jù)庫(kù)數(shù)據(jù)的一致性,需要主從復(fù)制。主從復(fù)制的實(shí)現(xiàn)原理是:mysql中有一種日志,叫做bin日志(二進(jìn)制日志),會(huì)記錄下所有修改過數(shù)據(jù)庫(kù)的sql語(yǔ)句。
六、優(yōu)化之緩存
6.1 緩存可以發(fā)生在這些層次:
(1)MySQL內(nèi)部:在系統(tǒng)調(diào)優(yōu)參數(shù)介紹了相關(guān)設(shè)置;
(2)數(shù)據(jù)訪問層:比如MyBatis針對(duì) SQL 語(yǔ)句做緩存,而 Hibernate 可以精確到單個(gè)記錄,這里緩存的對(duì)象主要是持久化對(duì)象Persistence Object;
(3)應(yīng)用服務(wù)層:這里可以通過編程手段對(duì)緩存做到更精準(zhǔn)的控制和更多的實(shí)現(xiàn)策略,這里緩存的對(duì)象是數(shù)據(jù)傳輸對(duì)象Data Transfer Object;
(4)Web層:針對(duì) web 頁(yè)面做緩存;
(5)瀏覽器客戶端:用戶端的緩存。
6.2 服務(wù)層的緩存實(shí)現(xiàn)
可以根據(jù)實(shí)際情況在一個(gè)層次或多個(gè)層次結(jié)合加入緩存。這里重點(diǎn)介紹下,目前主要有兩種方式:
(1)直寫式(Write Through):在數(shù)據(jù)寫入數(shù)據(jù)庫(kù)后,同時(shí)更新緩存,維持?jǐn)?shù)據(jù)庫(kù)與緩存的一致性。這也是當(dāng)前大多數(shù)應(yīng)用緩存框架如 Spring Cache 的工作方式。這種實(shí)現(xiàn)非常簡(jiǎn)單,同步好,但效率一般;
(2)回寫式(Write Back):當(dāng)有數(shù)據(jù)要寫入數(shù)據(jù)庫(kù)時(shí),只會(huì)更新緩存,然后異步批量的將緩存數(shù)據(jù)同步到數(shù)據(jù)庫(kù)上。這種實(shí)現(xiàn)比較復(fù)雜,需要較多的應(yīng)用邏輯,同時(shí)可能會(huì)產(chǎn)生數(shù)據(jù)庫(kù)與緩存的不同步,但效率非常高。
七、優(yōu)化之表分區(qū)
MySQL在 5.1 版引入的分區(qū)是一種簡(jiǎn)單的水平拆分,用戶需要在建表的時(shí)候加上分區(qū)參數(shù),對(duì)應(yīng)用是透明的無需修改代碼。
對(duì)用戶來說,分區(qū)表是一個(gè)獨(dú)立的邏輯表,但是底層由多個(gè)物理子表組成,實(shí)現(xiàn)分區(qū)的代碼實(shí)際上是通過對(duì)一組底層表的對(duì)象封裝,但對(duì)SQL層來說是一個(gè)完全封裝底層的黑盒子。 MySQL實(shí)現(xiàn)分區(qū)的方式也意味著索引也是按照分區(qū)的子表定義,沒有全局索引。
用戶的SQL語(yǔ)句是需要針對(duì)分區(qū)表做優(yōu)化,SQL 條件中要帶上分區(qū)條件的列,從而使查詢定位到少量的分區(qū)上,否則就會(huì)掃描全部分區(qū),可以通過EXPLAIN PARTITIONS來查看某條 SQL 語(yǔ)句會(huì)落在那些分區(qū)上,從而進(jìn)行 SQL 優(yōu)化
7.1 分區(qū)的好處是:
(1)可以讓單表存儲(chǔ)更多的數(shù)據(jù);
(2)分區(qū)表的數(shù)據(jù)更容易維護(hù),可以通過清楚整個(gè)分區(qū)批量刪除大量數(shù)據(jù),也可以增加新的分區(qū)來支持新插入的數(shù)據(jù)。另外,還可以對(duì)一個(gè)獨(dú)立分區(qū)進(jìn)行優(yōu)化、檢查、修復(fù)等操作;
(3)部分查詢能夠從查詢條件確定只落在少數(shù)分區(qū)上,速度會(huì)很快;
(4)分區(qū)表的數(shù)據(jù)還可以分布在不同的物理設(shè)備上,從而搞笑利用多個(gè)硬件設(shè)備
(5)可以使用分區(qū)表賴避免某些特殊瓶頸,例如InnoDB單個(gè)索引的互斥訪問、ext3 文件系統(tǒng)的 inode 鎖競(jìng)爭(zhēng);
(6)可以備份和恢復(fù)單個(gè)分區(qū)。
7.2 分區(qū)的限制和缺點(diǎn):
(1)一個(gè)表最多只能有1024個(gè)分區(qū);
(2)如果分區(qū)字段中有主鍵或者唯一索引的列,那么所有主鍵列和唯一索引列都必須包含進(jìn)來;
(3)分區(qū)表無法使用外鍵約束;
(4)NULL值會(huì)使分區(qū)過濾無效;
(5)所有分區(qū)必須使用相同的存儲(chǔ)引擎。
7.3 分區(qū)的類型:
(1)RANGE分區(qū):基于屬于一個(gè)給定連續(xù)區(qū)間的列值,把多行分配給分區(qū);
(2)LIST分區(qū):類似于按 RANGE 分區(qū),區(qū)別在于 LIST 分區(qū)是基于列值匹配一個(gè)離散值集合中的某個(gè)值來進(jìn)行選擇;
(3)HASH分區(qū):基于用戶定義的表達(dá)式的返回值來進(jìn)行選擇的分區(qū),該表達(dá)式使用將要插入到表中的這些行的列值進(jìn)行計(jì)算。這個(gè)函數(shù)可以包含 MySQL 中有效的、產(chǎn)生非負(fù)整數(shù)值的任何表達(dá)式;
(4)KEY分區(qū):類似于按 HASH 分區(qū),區(qū)別在于 KEY 分區(qū)只支持計(jì)算一列或多列,且 MySQL 服務(wù)器提供其自身的哈希函數(shù)。必須有一列或多列包含整數(shù)值。
7.4 分區(qū)適合的場(chǎng)景有:
最適合的場(chǎng)景數(shù)據(jù)的時(shí)間序列性比較強(qiáng),則可以按時(shí)間來分區(qū)
八、優(yōu)化之垂直拆分
8.1垂直拆分概述
垂直分庫(kù)是根據(jù)數(shù)據(jù)庫(kù)里面的數(shù)據(jù)表的相關(guān)性進(jìn)行拆分,比如:一個(gè)數(shù)據(jù)庫(kù)里面既存在用戶數(shù)據(jù),又存在訂單數(shù)據(jù),那么垂直拆分可以把用戶數(shù)據(jù)放到用戶庫(kù)、把訂單數(shù)據(jù)放到訂單庫(kù)。垂直分表是對(duì)數(shù)據(jù)表進(jìn)行垂直拆分的一種方式,常見的是把一個(gè)多字段的大表按常用字段和非常用字段進(jìn)行拆分,每個(gè)表里面的數(shù)據(jù)記錄數(shù)一般情況下是相同的,只是字段不一樣,使用主鍵關(guān)聯(lián)。
8.2 垂直拆分的優(yōu)點(diǎn)是:
(1)可以使得行數(shù)據(jù)變小,一個(gè)數(shù)據(jù)塊(Block)就能存放更多的數(shù)據(jù),在查詢時(shí)就會(huì)減少 I/O 次數(shù) (每次查詢時(shí)讀取的 Block 就少);
(2)可以達(dá)到最大化利用Cache的目的,具體在垂直拆分的時(shí)候可以將不常變的字段放一起,將經(jīng)常改變的放一起;
(3)數(shù)據(jù)維護(hù)簡(jiǎn)單。
8.3垂直拆分的缺點(diǎn)是:
(1)主鍵出現(xiàn)冗余,需要管理冗余列;
(2)會(huì)引起表連接JOIN操作(增加 CPU 開銷)可以通過在業(yè)務(wù)服務(wù)器上進(jìn)行 join 來減少數(shù)據(jù)庫(kù)壓力;
(3)依然存在單表數(shù)據(jù)量過大的問題(需要水平拆分);
(4)事務(wù)處理復(fù)雜。
九、優(yōu)化之水平拆分
9.1水平拆分概述
水平拆分是通過某種策略將數(shù)據(jù)分片來存儲(chǔ),分庫(kù)內(nèi)分表和分庫(kù)兩部分,每片數(shù)據(jù)會(huì)分散到不同的MySQL表或庫(kù),達(dá)到分布式的效果,能夠支持非常大的數(shù)據(jù)量。前面的表分區(qū)本質(zhì)上也是一種特殊的庫(kù)內(nèi)分表。
庫(kù)內(nèi)分表,僅僅是單純的解決了單一表數(shù)據(jù)過大的問題,由于沒有把表的數(shù)據(jù)分布到不同的機(jī)器上,因此對(duì)于減輕MySQL服務(wù)器的壓力來說,并沒有太大的作用,大家還是競(jìng)爭(zhēng)同一個(gè)物理機(jī)上的 IO、CPU、網(wǎng)絡(luò),這個(gè)就要通過分庫(kù)來解決。
9.2 水平拆分的優(yōu)點(diǎn)是:
(1)不存在單庫(kù)大數(shù)據(jù)和高并發(fā)的性能瓶頸;
(2)應(yīng)用端改造較少;
(3)提高了系統(tǒng)的穩(wěn)定性和負(fù)載能力。
9.3水平拆分的缺點(diǎn)是:
(1)分片事務(wù)一致性難以解決;
(2)跨節(jié)點(diǎn)Join性能差,邏輯復(fù)雜;
(3)數(shù)據(jù)多次擴(kuò)展難度跟維護(hù)量極大。
9.4水平拆分的分片原則
(1)能不分就不分,參考單表優(yōu)化;
(2)分片數(shù)量盡量少,分片盡量均勻分布在多個(gè)數(shù)據(jù)結(jié)點(diǎn)上,因?yàn)橐粋€(gè)查詢SQL跨分片越多,則總體性能越差,雖然要好于所有數(shù)據(jù)在一個(gè)分片的結(jié)果,只在必要的時(shí)候進(jìn)行擴(kuò)容,增加分片數(shù)量;
(3)分片規(guī)則需要慎重選擇做好提前規(guī)劃,分片規(guī)則的選擇,需要考慮數(shù)據(jù)的增長(zhǎng)模式,數(shù)據(jù)的訪問模式,分片關(guān)聯(lián)性問題,以及分片擴(kuò)容問題,最近的分片策略為范圍分片,枚舉分片,一致性Hash分片,這幾種分片都有利于擴(kuò)容;
(4)盡量不要在一個(gè)事務(wù)中的SQL跨越多個(gè)分片,分布式事務(wù)一直是個(gè)不好處理的問題;
(5)查詢條件盡量?jī)?yōu)化,盡量避免Select *的方式,大量數(shù)據(jù)結(jié)果集下,會(huì)消耗大量帶寬和 CPU 資源,查詢盡量避免返回大量結(jié)果集,并且盡量為頻繁使用的查詢語(yǔ)句建立索引;
(6)通過數(shù)據(jù)冗余和表分區(qū)賴降低跨庫(kù)Join的可能。
十、優(yōu)化之配置Mysql最大連接數(shù)
通常,mysql的最大連接數(shù)默認(rèn)是100, 最大可以達(dá)到16384。
10.1查看最大連接數(shù):
show variables like '%max_connections%';
10.2修改最大連接數(shù)
方法一:修改配置文件。推薦方法一
進(jìn)入MySQL安裝目錄 打開MySQL配置文件 my.ini 或 my.cnf查找 max_connections=100 修改為 max_connections=1000 服務(wù)里重起MySQL即可.
方法二:命令行修改。不推薦方法二
命令行登錄MySQL后。設(shè)置新的MySQL最大連接數(shù)為200:
MySQL> set global max_connections=200。
這種方式有個(gè)問題,就是設(shè)置的最大連接數(shù)只在mysql當(dāng)前服務(wù)進(jìn)程有效,一旦mysql重啟,又會(huì)恢復(fù)到初始狀態(tài)。因?yàn)閙ysql啟動(dòng)后的初始化工作是從其配置文件中讀取數(shù)據(jù)的,而這種方式?jīng)]有對(duì)其配置文件做更改。
十一、優(yōu)化之存儲(chǔ)引擎
目前廣泛使用的是MyISAM和InnoDB兩種引擎:
11.1 MyISAM
MyISAM引擎是MySQL 5.1及之前版本的默認(rèn)引擎,它的特點(diǎn)是:
(1)不支持行鎖,讀取時(shí)對(duì)需要讀到的所有表加鎖,寫入時(shí)則對(duì)表加排它鎖
(2)不支持事務(wù)
(3)不支持外鍵
(4)不支持崩潰后的安全恢復(fù)
(5)在表有讀取查詢的同時(shí),支持往表中插入新紀(jì)錄
(6)支持BLOB和TEXT的前500個(gè)字符索引,支持全文索引
(7)支持延遲更新索引,極大提升寫入性能
(8)對(duì)于不會(huì)進(jìn)行修改的表,支持壓縮表,極大減少磁盤空間占用
11.2 InnoDB
InnoDB在MySQL 5.5后成為默認(rèn)索引,它的特點(diǎn)是:
(1)支持行鎖,采用MVCC來支持高并發(fā)
(2)支持事務(wù)
(3)支持外鍵
(4)支持崩潰后的安全恢復(fù)
(5)不支持全文索引
11.3總體來講
MyISAM適合SELECT密集型的表,而InnoDB適合INSERT和UPDATE密集型的表