前言
該匯總參考的是 MySQL 官方8.0的使用手冊,以及《高性能 Mysql》第三版,關(guān)于學(xué)習(xí) MySQL 最好的方法就是搞懂原理然后實(shí)踐。
基礎(chǔ)知識
1、MySQL 是由 C、C++ 編寫
2、MySQL 可指定錯誤提示語言,但是沒有中文
3、注釋的兩種方法:# 和 --
4、命令行模式,在多行輸入需要取消時可以輸入 \c
5、命令行如果想保存登錄密碼,可以在 -p 后不加空格直接追加密碼,本地測試環(huán)境可以這么干
6、命令行模式,在查詢語句以 \G 結(jié)尾,可以讓查詢結(jié)果的字段垂直顯示
7、MySQL 由客戶端-服務(wù)端程序組成,mysqld 是服務(wù)端核心服務(wù),mysqld_safe 是 mysqld 的安全啟動方式,類似守護(hù)進(jìn)程,在 mysqld 的程序掛掉時可以自動拉起來,mysql.sever 是 MySQL 服務(wù)器啟動腳本,常用的命令有
mysql.server {start|stop|restart|reload|force-reload|status}
8、MySQL 可單獨(dú)設(shè)置時區(qū),默認(rèn)使用的是系統(tǒng)時區(qū)
9、安全更新模式 --safe-updates,該模式可以限制批量更新記錄時必須設(shè)置 where 查詢條件,如果沒有會報錯,另外還可以限制批量查詢返回的集合上限,設(shè)置方法為
set sql_safe_updateds=1, sql_select_limit=1000, max_join_size=100000;
10、MySQL 在連接服務(wù)端時會產(chǎn)生緩存,除了本機(jī)回環(huán)地址 127.0.0.1 以外的所有 ip 地址都會緩存,以此減少 DNS 查詢。連接錯誤時會記錄阻塞錯誤,當(dāng)連續(xù)錯誤次數(shù)達(dá)到 max_connect_errors 后會拒絕連接,如果想恢復(fù)訪問,只能清除緩存,或是等待 MySQL 緩存淘汰機(jī)制生效
11、MySQL 有調(diào)試模式,打開時后可以查看數(shù)據(jù)字典
12、MySQL 可以設(shè)置日志保存類型 log_output 是文件(FILE)、表格(table),還是 NONE,可以同時指定 3 種參數(shù),但是如果有 NONE 會優(yōu)先生效,也就是不記錄日志,所以通常打開慢查詢?nèi)罩局耙_保日志可以記錄
13、Mysql 開啟慢查詢?nèi)罩镜姆绞接袃煞N,會話開啟和配置開啟,前者只在當(dāng)前會話生效服務(wù)重啟后失效,后者是全局并且永久生效,同時可以設(shè)置超時時間,支持微秒級別,文件默認(rèn)保存在數(shù)據(jù)目錄中,以 host-name-slow.log 命名,可以手動修改文件保存位置和名稱,命令如下
# 會話開啟
slow_query_log=on;
#設(shè)置最大執(zhí)行時間
long_query_time=1;
#日志保存路徑
slow_query_log_file=/var/www/log/test.log
14、MySQL 安裝時可使用安全安裝 mysql_secure_installation 會要求設(shè)置 root 密碼、刪除 root 本機(jī)以外的訪問賬戶,刪除匿名賬戶、刪除 test 數(shù)據(jù)庫
15、MySQL 字符集后綴 _ci 表示不區(qū)分大小寫,utf8 和 utf8mb4 對比,前者支持 3 字節(jié),后者支持 4 字節(jié),后者可以支持存儲中文復(fù)雜字、emoji
16、MySQL 配置外網(wǎng)連接,第一先創(chuàng)建用戶:create user ‘root’@‘指定ip或是%無限制‘ identified by ‘密碼’;
第二授權(quán):grant all on . to ‘root’@‘指定ip或是%無限制’ with grant option; 第三步修改 MySQL 配置文件把綁定12.0.0.1的配置注釋
17、mysqladmin 是一個 MySQL 管理客戶端,不需要進(jìn)入 MySQL 就可以管理
18、mysqlcheck 是一個 MySQL 表檢查、修復(fù)、優(yōu)化、分析的客戶端,執(zhí)行檢查時會加讀鎖
19、mysqldumpslow 可以用來查看慢日志,結(jié)果是匯總處理過的數(shù)據(jù)
20、mysqldump 是備份的客戶端,但不會備份日志
進(jìn)階知識
-
存儲引擎
1、常用的存儲引擎為 Innodb 和 Myisam,其中以 Innodb 最為流行
2、Innodb 和 Myisam 最重要的區(qū)別為
| 引擎 | 表鎖 | 行鎖 | 事務(wù) | 外鍵 | 自動崩潰恢復(fù) | 熱備份 |
|---|---|---|---|---|---|---|
| Myisam | 支持 | 不支持 | 不支持 | 不支持 | 不支持 | 不支持 |
| Innodb | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
注:Myisam 在備份時會對加表鎖,阻塞寫入操作,所以不支持熱備份
3、事務(wù)是一組原子性的 SQL 查詢,事務(wù)內(nèi)的語句要不全部執(zhí)行成功,要不全部失敗,但是前提是事務(wù)內(nèi)操作的表引擎需要全部支持事務(wù),并且事務(wù)內(nèi)要避免混用引擎。事務(wù)的特點(diǎn)是,原子性、一致性、隔離性、持久性
4、Innodb 采用 MVCC 來支持高并發(fā),并且實(shí)現(xiàn)了四個標(biāo)準(zhǔn)的事務(wù)隔離級別,分別是 READ UNCOMMITTED (讀未提交)、READ COMMITTED (讀已提交)、REPEATABLE READ (可重復(fù)讀)、SERIALIZABLE (串行化),默認(rèn)事務(wù)是可重復(fù)讀
5、Innodb 的四種事務(wù)隔離級別對于數(shù)據(jù)一致性的影響
| 事務(wù) | 臟讀 | 不可重復(fù)讀 | 幻讀 |
|---|---|---|---|
| READ UNCOMMITTED (讀未提交) | 是 | 是 | 是 |
| READ COMMITTED (讀已提交) | 否 | 是 | 是 |
| REPEATABLE READ (可重復(fù)讀) | 否 | 否 | 是 |
| SERIALIZABLE (串行化) | 否 | 否 | 否 |
臟讀: 事務(wù)讀取的數(shù)據(jù)為其它事務(wù)更新但未提交的數(shù)據(jù),因?yàn)槠渌聞?wù)可能會回滾,導(dǎo)致數(shù)據(jù)不一致
不可重復(fù)讀: 事務(wù)只會讀取已經(jīng)提交的修改,這會造成在一個事務(wù)中兩次執(zhí)行同樣的查詢,可能會得到不一樣的結(jié)果
幻讀: 事務(wù)在同一個查詢中不同時間得到了不同的行集
6、MySQL 鎖的類型有很多種,不只是表鎖和行鎖,還存在意向鎖、間隙鎖、下一鍵鎖等,這里面有的鎖是顯性,有的是隱性,有的是用戶控制,有的是系統(tǒng)維護(hù),所以理解 MySQL 的鎖并不是一個簡單的事情。
7、記錄鎖也叫行鎖分為 共享鎖(s) 和 排他鎖(x),共享鎖允許事務(wù)持有讀取,獨(dú)占鎖允許事務(wù)持有更新,當(dāng)事務(wù)持有記錄的獨(dú)占鎖時,其它事務(wù)必須要等待,如果超過事務(wù)等待時間還未拿到鎖會提示超時。
8、意向鎖是一種表級鎖,由系統(tǒng)隱性維護(hù),主要是用來表明有人正在鎖定表或表中的行記錄,當(dāng)一個事務(wù)執(zhí)行了鎖定時,另一個事務(wù)如果要給表加鎖,就不需要去獲取具體的鎖,通過意向性鎖就可以知道表是否可以加鎖。
9、間隙鎖是在索引記錄的間隙使用的鎖,以下例子會鎖定 id 1~10的記錄
select * from logs where id between 1 and 10;
10、下一鍵鎖
11、插入意向鎖
12、AUTO-INC鎖
13、死鎖是指多個事務(wù)在同一資源上相互占用,并請求鎖定對方占用的資源,從而導(dǎo)致惡行循環(huán)的現(xiàn)象,MySQL 實(shí)現(xiàn)了死鎖檢測和死鎖超時機(jī)制,Innodb 處理死鎖的方式是,將擁有最少插入、更新或刪除行數(shù)的事務(wù)回滾。
# 死鎖檢測默認(rèn)開啟
innodb_deadlock_detect=on
# 死鎖默認(rèn)超時時間
innodb_lock_wait_timeout=50
14、查看死鎖的方法,開啟性能模式,通過 data_locks,data_lock_waits 查看鎖定信息,取代了8.0版本之前 information_schema.innodb_lock 和 information_schema.innodb_lock_waits
15、從絕對意義上消除死鎖是不可能的,但是可以通過一些手段盡量降低死鎖的發(fā)生概率
- 對于相同的程序盡量以相同的順序訪問表
- 避免使用大事務(wù),盡量拆分成小事務(wù),大事務(wù)占用資源多,時間長,與其它事務(wù)產(chǎn)生沖突的概率就大
- 為表添加合適的索引,減少數(shù)據(jù)查詢的無用數(shù)據(jù)鎖定
16、行鎖的優(yōu)點(diǎn)是鎖定粒度小,發(fā)生鎖沖突的概率低,并且對并發(fā)的支持度高,缺點(diǎn)是鎖的開銷會變大
17、樂觀鎖和悲觀鎖不是一種鎖,而是一種程序設(shè)計(jì)思想,樂觀鎖假設(shè)在事務(wù)執(zhí)行前預(yù)期不會有其它事務(wù)對數(shù)據(jù)修改不會發(fā)生沖突,只在最終事務(wù)提交時檢測數(shù)據(jù)是否被修改,悲觀鎖時在事務(wù)執(zhí)行前就預(yù)期數(shù)據(jù)會被其它事務(wù)修改,提前對數(shù)據(jù)進(jìn)行鎖定,避免其它事務(wù)修改數(shù)據(jù)。樂觀鎖的適用場景偏向讀多,悲觀鎖則是寫多。
- 樂觀鎖可以通過對記錄加版本號或時間戳來實(shí)現(xiàn),在記錄查詢時獲取版本號,只要記錄發(fā)生變更就更新版本號,在最終提交時檢測版本號是否為最初查詢的,如果不一致就無法更新
- 悲觀鎖可以通過給記錄添加排他鎖來實(shí)現(xiàn)
-
數(shù)據(jù)類型
1、優(yōu)化數(shù)據(jù)類型通用原則
- 選擇符合業(yè)務(wù)的最小數(shù)據(jù)類型,更小的數(shù)據(jù)類型占用更少的磁盤、內(nèi)存和 CPU 緩存,并且處理需要的 CPU 周期更少
- 簡單就好,這樣可以需要更少的 CPU 周期,例如存儲 IP 地址轉(zhuǎn)為整型會比適用字符串更高效
- 盡量避免使用 NULL,NULL 的存儲會消耗更多的存儲空間,并且在索引統(tǒng)計(jì)時增加搜索難度
-指定合適的數(shù)據(jù)寬度,更長的寬度會消耗更多的內(nèi)存,因?yàn)?MySQL 通常會分配固定大小的內(nèi)存塊來保存內(nèi)部值,在用內(nèi)存對臨時表進(jìn)行排序或操作時影響會很大
2、整數(shù)類型在設(shè)置時,可以指定寬度,例如 int(11),這對大部分應(yīng)用是沒有意義的,它不會限制值的合法范圍,只對填充零有影響,例如現(xiàn)在存儲的值為1,選擇填充零會變?yōu)?0000000001。
3、varchar 和 char 是最主要的字符串類型,varchar 類型用于存儲可變長字符,char 類型用于存儲定長字符,數(shù)據(jù)寬度的設(shè)置在這里是有意義,指定多長寬度,就最多存多少字符。
這里要特別聲明【字符】和 【字節(jié)】是不等的,字符代表字符串的長度,字節(jié)代表該數(shù)據(jù)結(jié)構(gòu)存儲字符需要的字節(jié)單位,影響字節(jié)數(shù)的因素是字符集配置,例如:字符集 utfbmb4 使用的是 4 字節(jié)存儲,utfb8 使用 3 字節(jié)存儲,同一個字符串“我愛祖國”,前者需要 16 個字節(jié)存儲,后者需要 12 個字節(jié)。
varchar 的寬度范圍是 0 ~ 65535,但實(shí)際能設(shè)置的最大寬度是有限制的,MySQL 內(nèi)部對于行是有 65535 字節(jié)最大限制的,也就是說所有列的最大字節(jié)數(shù)總和是不能超過這個值的。除了 MySQL 自身的限制,數(shù)據(jù)庫引擎也會對行大小產(chǎn)生限制,Innodb 的默認(rèn)頁大小 innodb_page_size 為 16KB, 行大小不能超過它的一半值,但 64KB 頁面限制小于 16KB。varchar 默認(rèn)會有另外的字節(jié)存儲字節(jié)長度,如果值小于 255 字節(jié),使用 1 個字節(jié)存儲,反之使用 2 個字節(jié)存儲。
char 的最大寬度為255,默認(rèn)可以保存末尾空格,但在取出時,會自動刪除末尾空格。
4、Blob 和 Text 都是為存儲很大的數(shù)據(jù)而設(shè)計(jì)的字符串類型,分別采用二進(jìn)制和字符串方式存儲,與其他類型不同,MYSQL 把這兩種數(shù)據(jù)格式當(dāng)成一個獨(dú)立的對象存儲,Innodb 會有專門的外部存儲區(qū)域來進(jìn)行存儲,此時每個值在行內(nèi)需要1~4個字節(jié)存儲一個指針,然后在外部區(qū)域存儲實(shí)際的值。這兩個類型在列中只占 9 ~ 12 字節(jié)。
5、日期時間常用的格式為 datetime 和 timestamp,前者為 8 字節(jié)存儲,時間值為存儲的真實(shí)值,但是時間范圍是 1001~9999,后者為 4 字節(jié)存儲,時間值在取出時根據(jù)時區(qū)顯示,時間范圍是 1970~2038。
- 數(shù)據(jù)庫設(shè)計(jì)的范式和反范式
1、范式是 符合某一種級別的關(guān)系模式的集合,表示一個關(guān)系內(nèi)部各屬性之間的聯(lián)系的合理化程度,而數(shù)據(jù)庫庫范式就可以理解為創(chuàng)建表時的一種設(shè)計(jì)原則,數(shù)據(jù)庫范式有六種:第一范式、第二范式、第三范式、巴斯-科德范式、第四范式 和 第五范式,但通常只需要用到前三范式即可。
第一范式:每個列的數(shù)據(jù)為最小單位,不可拆分
第二范式:在第一范式基礎(chǔ)上,確保每個非主鍵列都依賴于主鍵,而不是主鍵的一部分(聯(lián)合主鍵)
第三范式:在第二范式基礎(chǔ)上,確保每個非主鍵列不相互依賴
2、范式的優(yōu)點(diǎn)和缺點(diǎn)
【優(yōu)點(diǎn)】
- 更新操作快
- 表數(shù)據(jù)冗余小
- 表體積小,可以更好的放在內(nèi)存里,執(zhí)行速度會更快
【缺點(diǎn)】
- 通常需要關(guān)聯(lián),有時會造成很大的開銷
3、反范式的優(yōu)點(diǎn)和缺點(diǎn)
【優(yōu)點(diǎn)】
- 通常不需要關(guān)聯(lián),查詢效率更高
【缺點(diǎn)】
- 更新操作開銷大
- 造成大量冗余
-
索引
1、索引是存儲引擎用于快速找到記錄的一種數(shù)據(jù)結(jié)構(gòu)。
2、索引的方式分為:B-Tree 索引和 哈希索引
- MyISAM 使用前綴壓縮技術(shù)使得索引更小,但 Innodb 則按照原數(shù)據(jù)格式進(jìn)行存儲
- B-Tree 索引適用于全鍵值、鍵值范圍或前綴查找,索引從最左側(cè)開始查找,否則無法使用索引,不能跳過跳過索引的列
- 哈希索引只包含哈希值和行指針,不存儲字段值,所以需要回表,哈希索引不是按照索引順序存儲的,因此無法排序,哈希索引也不支持部分索引列匹配查找
3、索引類型有普通索引、唯一索引、全文索引、空間索引。
4、索引的優(yōu)點(diǎn)
- 減少了服務(wù)器需要掃描的數(shù)據(jù)量
- 索引可以幫助服務(wù)器避免排序和臨時表
- 索引可以將隨機(jī) I/O 變?yōu)轫樞?I/O
注:索引并不總是最好的工具,只有當(dāng)索引幫助存儲引擎快速查找到記錄帶來的好處大于其帶來的額外工作時,索引才是有效的,對于非常小的表,大部分情況下全表掃描更高效,對于特大型表,例如 TB 級別的數(shù)據(jù),建立索引和維護(hù)的成本會很高,在這種情況下塊級別元數(shù)據(jù)技術(shù)比索引更有效。
5、高性能的索引策略
- 索引列不能是表達(dá)式的一部分,也不能是函數(shù)的參數(shù)
- 設(shè)置選擇性高的列作為索引,索引選擇性的計(jì)算方法為:不重復(fù)的索引值(基數(shù))和數(shù)據(jù)表的記錄數(shù)的比值,該值越高,代表索引查詢效率越高,因?yàn)榭梢宰?MySQL 在查詢時過濾掉更多的行
- 對于 BLOB、TEXT 或者很長的 VARCHAR 類型,必須使用前綴索引,因?yàn)?MySQL 不允許這些列的完整長度,但是前綴索引無法使用 order by 和 group by,也無法使用前綴索引做覆蓋索引
- 避免在多個列上建立單獨(dú)的索引,這樣并不能提高查詢效率,例如 explain select from_id,scene from logs where from_id=1 and status =1, 這兩個字段分別建立單獨(dú)索引,查看執(zhí)行計(jì)劃可以發(fā)現(xiàn) TYPE 為 index_merge,這是 MySQL 使用了索引合并策略,通常遇到這種情況說明索引該優(yōu)化了
- 聯(lián)合索引遵循最左匹配原則,索引查找需要從最左側(cè)開始,確定索引順序非常重要,通常將選擇性最高的列放到索引最前列,聯(lián)合索引最大可選擇 16 列
- 聚簇索引并不是一個單獨(dú)的索引類型,而是一種數(shù)據(jù)存儲方式,聚簇索引的數(shù)據(jù)行存儲在索引的葉子頁,聚簇索引通常是表的主鍵,但是表如果沒有主鍵,會默認(rèn)使用第一個非NULL唯一索引,如果唯一索引也沒有,Innodb 會生成一個隱式的聚簇索引,通過聚簇索引訪問行的速度很快,因?yàn)樗饕苯又赶虬袛?shù)據(jù)的頁面,另外聚簇索引的列不能有 NULL 值
- 二級索引是聚簇索引以外的索引,在 Innodb 中二級索引的每條記錄都包含該行的主鍵列,以及為二級索引指定的列,如果主鍵很長,二級索引占用的空間就更多,所以主鍵越短越好
- 覆蓋索引是通過索引直接獲取列的數(shù)據(jù),這樣就不需要回表了,覆蓋索引必須要存儲索引的值,而哈希索引、全文索引、空間索引都不存儲索引列的值,所以 MySQL 只能使用 B-Tree 索引做覆蓋索引
- MySQL 有兩種方式可以生成有序的結(jié)果:通過排序操作,或者按索引順序掃描,如果 EXPLAIN 出來的 type 列的值為 index, 則說明 MySQL 使用了索引掃描來做排序,如果索引不能覆蓋查詢所需的全部列,那就需要再次回表查詢一次對應(yīng)的行,這基本都是隨機(jī) I/O,在 I/O 密集型的工作負(fù)載時,速度不如全表掃描,所以索引設(shè)計(jì)時最好能同時滿足查詢和排序
- 冗余和重復(fù)的索引是指在相同列上創(chuàng)建多個索引,例如在 A 列上既有(A,B)索引,也有(A)索引,冗余索引是否需要要根據(jù)實(shí)際場景,如果擴(kuò)展原有的索引會導(dǎo)致其變的太大,從而影響到其它使用該索引的查詢,可以考慮冗余索引
- 聯(lián)合索引的創(chuàng)建要根據(jù)選擇性來確定,但是有的列的選擇性很低,但又很高頻,還是可以使用的,例如:性別(sex)、國家(country)和 登錄狀態(tài)(status)這種字段,如果建立聯(lián)合索引就會有很多組合,(sex,country,status),(country,sex,status) 等,如果按不同的查詢場景建立多個索引是不合適的,可以使用一種 in 查詢的方法繞過限制,比如按照 (sex,country,status) 創(chuàng)建的索引,只想查國家,我們可以對 sex 字段使用 in 查詢,in(男,女)來讓 Innodb 使用到索引,當(dāng)然這種方法只適合 in 中數(shù)據(jù)少的情況
-
查詢性能優(yōu)化
1、查詢性能優(yōu)化關(guān)注的應(yīng)該是查詢的響應(yīng)時間,提升響應(yīng)時間是優(yōu)化的基本思路
2、查詢性能低下最基本的原因是訪問的數(shù)據(jù)太多,可以通過以下兩個步驟來分析
- 確認(rèn)應(yīng)用程序是否在檢索大量超過需要的數(shù)據(jù)(應(yīng)用層)
- 確認(rèn) MySQL 服務(wù)器層是否在分析大量超過需要的數(shù)據(jù)行(服務(wù)層)
3、檢查是否向數(shù)據(jù)庫請求了不需要的數(shù)據(jù),關(guān)于不需要的數(shù)據(jù)有以下定義
- 只需要用到少量行,但是查詢了所有行然后再從中取出需要的行
- 多表關(guān)聯(lián)時返回所有的列
- 單表 select * 查找所有的列
- 重復(fù)查詢相同的數(shù)據(jù)
4、檢查 MySQL 是否在掃描額外的記錄,衡量指標(biāo)有:響應(yīng)時間、掃描的行數(shù)、返回的行數(shù)
- 響應(yīng)時間是兩個部分之和:服務(wù)時間和排隊(duì)時間。服務(wù)時間是指數(shù)據(jù)庫處理這個查詢真正花了多少時間。排隊(duì)時間是指服務(wù)器因?yàn)榈却承┵Y源而沒有真正執(zhí)行查詢的時間,可能是等待 I/O 操作完成,也可能是等待行鎖。
- 關(guān)于使用復(fù)雜查詢還是多個單個查詢,從很早我聽到的建議就是盡量使用復(fù)雜查詢,但在如今服務(wù)器帶寬和性能都得到大幅提升,已經(jīng)不需要再拘泥于這種約束,可以使用多個小查詢替代復(fù)雜查詢,小查詢還有以下的優(yōu)勢
1、更加方便的做緩存
2、減少鎖的競爭
3、在應(yīng)用層做關(guān)聯(lián),可以更容易地?cái)?shù)據(jù)庫進(jìn)行拆分,更容易做到高性能和可擴(kuò)展
4、查詢本身效率也可能得到提升,比如 laravel 的模型關(guān)聯(lián)并不是通過 Join 去連表,而是通過 in 來查詢
5、MySQL 執(zhí)行查詢的步驟
1、客戶端發(fā)送一條查詢給服務(wù)器
2、服務(wù)器進(jìn)行 SQL 解析、預(yù)處理、再由優(yōu)化器生成對應(yīng)的執(zhí)行計(jì)劃
3、MySQL 根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃,調(diào)用存儲引擎的 API 來執(zhí)行查詢
4、將結(jié)果返回給客戶端
6、MySQL 客戶端和服務(wù)器的通信協(xié)議是“雙半工”,關(guān)于通信的方式可以分為:單工通信、半雙工、全雙工
- 單工通信就是接收端和發(fā)送端已經(jīng)固定,接收端只能接收數(shù)據(jù),發(fā)送到只能發(fā)送數(shù)據(jù),線路上的數(shù)據(jù)流永遠(yuǎn)是單向的,例如電視遙控器
- 半雙工通信就是在同一時刻,線路上只允許一個方向上的數(shù)據(jù)傳輸
- 全雙工通信就是在同一時刻,線路上允許兩個方向上的數(shù)據(jù)傳輸,例如打電話
MySQL 半雙工的通信方式讓通信變得簡單,但也從其它方面限制了 MySQL,一個明顯的限制是,無法進(jìn)行流量控制。一旦一端開始發(fā)送消息,另一端要接收完整消息才能進(jìn)行響應(yīng),MySQL 客戶端用一個單獨(dú)的數(shù)據(jù)包將查詢傳遞給服務(wù)器,當(dāng)查詢語句很長時,參數(shù) max_allowed_packet 就很重要了。
7、MySQL 線程連接狀態(tài),更多的線程狀態(tài)可以查看 MySQL線程狀態(tài)
- sleep 線程正在等待客戶端發(fā)送新的請求
- query 線程正在執(zhí)行查詢或者正在將結(jié)果發(fā)送到客戶端
- locked 在 MySQL 服務(wù)器層,該線程正在等待表鎖,在存儲引擎級別實(shí)現(xiàn)的鎖,并不會體現(xiàn)在線程狀態(tài)中
8、count() 查詢
count() 是一個特殊的函數(shù),有兩種非常不同的作用:它可以統(tǒng)計(jì)某個列值的數(shù)量,也可以統(tǒng)計(jì)行數(shù)。在統(tǒng)計(jì)列值時會過濾掉 NULL 值,另外用 count(*) 時可以統(tǒng)計(jì)查詢到的記錄總行數(shù),在這種情況下通配符 * 不會擴(kuò)展成所有的列,它會忽略所有的列而直接統(tǒng)計(jì)所有的行數(shù),并不會如網(wǎng)上所說對性能有影響
9、MyISAM 的 count 查詢總行數(shù)的速度非???,這是因?yàn)?MyISAM 內(nèi)部維護(hù)有總行數(shù),但是還有個前提,即查詢沒有任何的 where 條件,因?yàn)榇藭r不需要去計(jì)算實(shí)時的行數(shù),如果需要實(shí)時計(jì)算總行數(shù),那和其它的引擎并沒有區(qū)別