搜尋
首頁資料庫mysql教程mysql 單機資料庫優化的一些實踐_MySQL

資料庫最佳化有很多可以講,依照支撐的資料量來分可以分成兩個階段:單機資料庫和分庫分錶,前者一般可以支撐500W或10G以內的數據,超過這個值則需要考慮分庫分表。另外,一般大企業面試往往會從單機資料庫問起,一步一步問到分庫分錶,中間會穿插很多資料庫優化的問題。本文試圖描述單機資料庫最佳化的一些實踐,資料庫基於mysql,如有不合理的地方,歡迎指正。

1、表結構最佳化

在開始做一個應用的時候,資料庫的表結構設計往往會影響應用程式後期的效能,特別是使用者量上來了以後的效能。因此,表結構優化是一個很重要的步驟。

1.1、字符集

一般來說盡量選擇UTF-8,雖然在存中午的時候GBK比UTF-8使用的存儲空間少,但是UTF-8兼容各國語言,其實我們不必為了這點存儲空間而犧牲了擴展性。事實上,後期如果要從GBK轉為UTF-8所要付出的代價是很高的,需要進行資料遷移,而儲存空間完全可以用花錢擴充硬碟來解決。

1.2、主鍵

在使用mysql的innodb的時候,innodb的底層儲存模型是B+樹,它使用主鍵作為聚集索引,使用插入的資料作為葉子節點,透過主鍵可以很快找到葉子節點,從而快速取得記錄。因此在設計表的時候需要增加一個主鍵,而且最好要自增。因為自增主鍵可以讓插入的資料以主鍵順序插入到底層的B+樹的葉子節點中,由於是按序的,這種插入幾乎不需要去移動已有的其它數據,所以插入效率很高。如果主鍵不是自增的,那麼每次主鍵的值近似隨機,這時候就有可能需要移動大量資料來確保B+樹的特性,增加了不必要的開銷。

1.3、字段

1.3.1、建了索引的欄位必須加上not null約束,並且設定default值

1.3.2、不建議使用float、double來存小數,防止精度損失,建議使用decimal

1.3.3、不建議使用Text/blob來保存大量數據,因為對大文本的讀寫會造成比較大的I/O開銷,同時佔用mysql的緩存,高並發下會極大的降低數據庫的吞吐量,建議將大文本資料保存在專門的文件存儲系統中,mysql中只保存這個文件的訪問地址,例如博客文章可以保存在文件中,mysql中只保存文件的相對地址。

1.3.4、varchar類型長度建議不要超過8K。

1.3.5、時間類型建議使用Datetime,不要使用timestamp,雖然Datetime佔用8個字節,而timestamp只佔用4個字節,但是後者要保證非空,而且後者是對時區敏感的。

1.3.6、建議表中增加gmt_create和gmt_modified兩個字段,用來記錄資料建立的修改時間。這兩個欄位建立的原因是方便查問題。

1.4、索引建立

1.4.1、這個階段由於對業務並不了解,所以盡量不要盲目加索引,只為一些一定會用到索引的字段加普通索引。

1.4.2、建立innodb單列索引的長度不要超過767bytes,如果超過會用前255bytes作為前綴索引

1.4.3、建立innodb組合索引的各列索引長度不要超過767bytes,總共加起來不要超過3072bytes

2、SQL最佳化

一般來說sql就那麼幾種:基本的增刪改查,分頁查詢,範圍查詢,模糊搜索,多表連接

2.1、基本查詢

一般查詢需要走索引,如果沒有索引建議修改查詢,把有索引的那個字段加上,如果由於業務場景沒法使用這個字段,那麼需要看這個查詢調用量大不大,如果大,比如每天調用10W+,這就需要新增索引,如果不大,例如每天呼叫100+,則可以考慮保持原樣。另外,select * 盡量少用,用到什麼欄位就在sql語句加什麼,不必要的欄位就別查了,浪費I/O和記憶體空間。

2.2、高效分頁

limit m,n其實質就是先執行limit m+n,然後從第m行取n行,這樣當limit翻頁越往後翻m越大,性能越低。如

select * from A limit 100000,10,這種sql語句的效能是很差的,建議改成下面的版本:

selec id,name,age from A where id >=(select id from A limit 100000,1) limit 10

2.3、範圍查詢

範圍查詢包括between、大於、小於、in。 Mysql中的in查詢的條件有數量的限制,若數量較小可以走索引查詢,若數量較大,就成了全表掃描了。而between、大於、小於等,這些查詢不會走索引,所以盡量放在走索引的查詢條件之後。

2.4、模糊查詢like

使用like %name%這樣的語句是不會走索引的,相當於全表掃描,資料量小的時候不會有太大的問題,資料量大了以後效能會下降的很厲害,建議資料量大了以後使用搜尋引擎來代替這種模糊搜索,實在不行也要在模糊查詢前加個能走索引的條件。

2.5、多表連接

子查詢和join都可以實現在多張表之間取數據,但是子查詢效能較差,建議將子查詢改成join。對於mysql的join,它用的是Nested Loop Join演算法,也就是透過前一個表格查詢的結果集去後一個表中查詢,例如前一個表的結果集是100條數據,後一個表有10W數據,那就需要在100*10W的資料集合中去過濾得到最終的結果集。因此,盡量用小結果集的表去和大表做join,同時在join的欄位上建立索引,如果建不了索引,就需要設定足夠大的join buffer size。如果以上的技巧都無法解決join所帶來的效能下降的問題,那乾脆就別用join了,將一次join查詢拆分成兩次簡單查詢。另外,多表連接盡量不要超過三張表,超過三張表一般來說會很差,建議拆分sql。

3、資料庫連接池最佳化

資料庫連接池本質上是一種緩存,它是一種抗高並發的手段。資料庫連線池最佳化主要是對參數進行最佳化,一般我們使用DBCP連線池,它的具體參數如下:

3.1  initialSize

初始連線數,這裡的初始指的是第一次getConnection的時候,而不是應用啟動的時候。初始值可以設定為同時數量的歷史平均值

3.2、minIdle

最小保留的空閒連線數。 DBCP會在背景開啟一個回收空閒連線的線程,當該執行緒進行空閒連線回收的時候,會保留minIdle個連線數。一般設定為5,並發量實在很小可以設定為1.

3.3、maxIdle

最大保留的空閒連線數,依照業務並發高峰設定。例如並發高峰為20,那麼當高峰過去後,這些連接不會馬上被回收,如果過一小段時間又來一個高峰,那麼連接池就可以復用這些空閒連接而不需要頻繁創建和關閉連接。

3.4、maxActive

最大活躍連線數,依照可以接受的並發極值設定。例如單機並發量可接受的極值是100,那麼這個maxActive設定成100後,就只能同時為100個請求服務,多餘的請求會在最大等待時間之後被拋棄。這個值必須設置,可以防止惡意的並發攻擊,保護資料庫。

3.5、maxWait

取得連線的最大等待時間,建議設定的短一點,例如3s,這樣可以讓請求快速失敗,因為一個請求在等待取得連線的時候,執行緒是不可以被釋放的,而單機的執行緒並發量是有限的,如果這個時間設定的過長,例如網上建議的60s,那麼這個線程在這60s內是無法被釋放的,只要這種請求一多,應用的可用線程就少了,服務就變得不可用了。

3.6、minEvictableIdleTimeMillis

連線保持空閒而不被回收的時間,預設30分鐘。

3.7、validationQuery

用來偵測連線是否有效的sql語句,一般是一條簡單的sql,建議設定

3.8、testOnBorrow

申請連線的時候對連線進行偵測,不建議開啟,嚴重影響效能

3.9、testOnReturn

歸還連線的時候對連線進行偵測,不建議開啟,嚴重影響效能

3.10、testWhileIdle

開啟了以後,後台清理連線的執行緒會沒隔一段時間對空閒連線進行validateObject,如果連線失效則會清除,不影響效能,建議開啟

3.11、numTestsPerEvictionRun

代表每次檢查連結的數量,建議設定和max​​Active一樣大,這樣每次可以有效檢查所有的連結。

3.12、預熱連接池

對於連接池,建議在啟動應用的時候進行預熱,在還未對外提供訪問之前進行簡單的sql查詢,讓連接池充滿必要的連接數。

4、索引最佳化

當資料量增加到一定程度後,靠sql優化已經無法提升效能了,這時候就需要祭出大招:索引。索引有三級,一般來說掌握這三級就足夠了,另外,對於建立索引的字段,需要考慮其選擇性。

4.1、一級索引

在where後面的條件上建立索引,單列可以建立普通索引,多列則建立組合索引。組合索引需要注意最左前綴原則。

4.2、二級索引

如果有被order by或group by用到的字段,則可以考慮在這個字段上建立索引,這樣一來,由於索引天然有序,可以避免order by以及group by所帶來的排序,從而提高性能。

4.3、三級索引

如果上面兩招還不行,那麼就把所查詢的字段也加上索引,這時候就形成了所謂的索引覆蓋,這樣做可以減少一次I/O操作,因為mysql在查詢資料的時候,是先查主鍵索引,然後根據主鍵索引去查普通索引,然後根據普通索引去查相對應的記錄。如果我們所需要的記錄在普通索引裡都有,那就不需要第三步了。當然,這種建索引的方式比較極端,不適合一般場景。

4.4、索引的選擇性

在建立索引的時候,盡量在選擇性高的字段上建立。什麼是選擇性高呢?所謂選擇性高就是透過這個字段查出來的資料量少,例如依照名字查一個人的信息,查出來的資料量一般會很少,而依照性別查則可能會把資料庫一半的資料都查出來,所以,名字是一個選擇性高的字段,而性別是個選擇性低的字段。

5、歷史資料歸檔

當資料量到了一年增加500W條的時候,索引也無能為力,這時候一般的思路都是考慮分庫分錶。如果業務沒有爆發式成長,但是資料的確在緩慢增加,則可以不考慮分庫分錶這種複雜的技術手段,而是進行歷史資料歸檔。我們針對生命週期已經完成的歷史數據,例如6個月之前的數據,進行歸檔。我們可以使用quartz的調度任務在凌晨定時將6個月之前的資料查出來,然後存入遠端的hbase伺服器。當然,我們也需要提供歷史資料的查詢接口,以備不時之需。

以上就是對mysql 單機資料庫的最佳化資料整理,後續繼續補充相關資料,謝謝大家對本站的支持!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
图文详解mysql架构原理图文详解mysql架构原理May 17, 2022 pm 05:54 PM

本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了关于架构原理的相关内容,MySQL Server架构自顶向下大致可以分网络连接层、服务层、存储引擎层和系统文件层,下面一起来看一下,希望对大家有帮助。

mysql的msi与zip版本有什么区别mysql的msi与zip版本有什么区别May 16, 2022 pm 04:33 PM

mysql的msi与zip版本的区别:1、zip包含的安装程序是一种主动安装,而msi包含的是被installer所用的安装文件以提交请求的方式安装;2、zip是一种数据压缩和文档存储的文件格式,msi是微软格式的安装包。

mysql怎么去掉第一个字符mysql怎么去掉第一个字符May 19, 2022 am 10:21 AM

方法:1、利用right函数,语法为“update 表名 set 指定字段 = right(指定字段, length(指定字段)-1)...”;2、利用substring函数,语法为“select substring(指定字段,2)..”。

mysql怎么替换换行符mysql怎么替换换行符Apr 18, 2022 pm 03:14 PM

在mysql中,可以利用char()和REPLACE()函数来替换换行符;REPLACE()函数可以用新字符串替换列中的换行符,而换行符可使用“char(13)”来表示,语法为“replace(字段名,char(13),'新字符串') ”。

mysql怎么将varchar转换为int类型mysql怎么将varchar转换为int类型May 12, 2022 pm 04:51 PM

转换方法:1、利用cast函数,语法“select * from 表名 order by cast(字段名 as SIGNED)”;2、利用“select * from 表名 order by CONVERT(字段名,SIGNED)”语句。

MySQL复制技术之异步复制和半同步复制MySQL复制技术之异步复制和半同步复制Apr 25, 2022 pm 07:21 PM

本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了关于MySQL复制技术的相关问题,包括了异步复制、半同步复制等等内容,下面一起来看一下,希望对大家有帮助。

mysql怎么判断是否是数字类型mysql怎么判断是否是数字类型May 16, 2022 am 10:09 AM

在mysql中,可以利用REGEXP运算符判断数据是否是数字类型,语法为“String REGEXP '[^0-9.]'”;该运算符是正则表达式的缩写,若数据字符中含有数字时,返回的结果是true,反之返回的结果是false。

带你把MySQL索引吃透了带你把MySQL索引吃透了Apr 22, 2022 am 11:48 AM

本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了mysql高级篇的一些问题,包括了索引是什么、索引底层实现等等问题,下面一起来看一下,希望对大家有帮助。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具