數據庫的管理是一個很是專業的事情,對數據庫的調優、監控通常是由數據庫工程師完成,可是開發人員也常常與數據庫打交道,即便是簡單的增刪改查也是有不少竅門,這裏,一塊兒來聊聊數據庫中很容易忽略的問題。mysql
先說說咱們經常使用的類型的存儲長度:redis
列類型 | 存儲長度 |
---|---|
tinyint | 1字節 |
smallint | 2字節 |
int | 4字節 |
bigint | 8字節 |
float | 4字節 |
decimal(m,d) | 0-4字節 |
datetime | 8字節 |
timestamp | 4字節 |
char(m) | m個字節 |
varchar(m) | 可變長度 |
text | 可變長度 |
很明顯,不一樣的類型存儲的長度有很大區別的,對查詢的效率有影響,字段長度對索引的影響是很大的。算法
不論是uuid,仍是guid,使用的時候都是爲了不同時生成重複的ID,可是建議考慮其餘方案,緣由以下:sql
推薦的方案用bigint(首選),或者char來存儲,生成方式參考snowflake的算法,有順序、長度固定、比uuid更短,固然,也幾乎不會重複。mongodb
單表查詢的優點不少,查詢效率極高,便於分表分庫擴展,可是不少時候你們都以爲真正實現起來不太現實,徹底失去了關係數據庫的意義,可是單表的性能優點太明顯,通常總會有辦法解決的:數據庫
若是考慮都後期數據量大,須要分表分庫,就應該儘早實時單表查詢,如今的數據庫分表分庫的中間件基本都沒法支持聯表查詢。即便如mycat最多支持兩個表的聯表查詢,可是也有很明顯的性能損耗。緩存
索引的優點這裏就很少說了,索引使用不當會有反效果:微信
提出這個方案相信會獲得不少人的反對,可是我相信這個結論仍是很是適合數據量大的場景。多查幾回數據庫有這麼幾個弊端:網絡
其實,這兩個問題在如今基本均可以忽略的,數據庫和應用的鏈接基本都是內網,這個網絡鏈接的效率仍是很高的。數據庫對鏈接池的優化已經比較成熟了,鏈接數只要不是太多,影響也不會太嚴重,可是多查幾回的優點卻不少:框架
固然,多查幾回這個度必定要把握。千萬不要在一個循環裏面查詢數據庫。咱們也應該儘可能減小查詢數據庫的次數。咱們能夠接受1次查詢變2次查詢,若是你變成10次查詢,那就要放棄了。
舉個例子:
查詢商品的時候,須要顯示分類表的分類名
select category.name,product.name from product inner join category on p.categoryid=category.id
建議的方式:
select categoryid,name from product select categoryname from category where categoryid in ('','','','')
固然,你能夠再優化一下,查詢分類名以前,對product的categoryid排序一下,這樣速度更快。由於咱們前面已經用snowflake生成了有順序的主鍵了。
補充一下,in的效率並非你想象的那麼慢,若是保持在100個節點(不少書籍介紹1000個節點,咱們保守一點),性能仍是很高的。
不少用過 .net Entity Framework 的人都說這個框架太慢,其實慢主要是兩點:錯誤的使用延遲加載(外鍵關聯)、生成SQL編譯太慢。Entity Framework生成的SQL腳本有太多沒用的東西,致使編譯太慢。
數據庫腳本儘可能使用簡單的,不要用太長的一個SQL腳本,會致使初次執行的時候,編譯SQL腳本花費太多的時間。
聚合操做如count,group等,是數據庫性能的大殺手,常常會出現大面積的表掃描和索表的狀況,因此你們能看到不少平臺都把數量的計算給隱藏了,商品查詢不去實時顯示count的結果。如淘寶,就不顯示查詢結果的數量,只是顯示前100頁。
避免聚合操做的方法就是將實時的count計算結果用字段去存儲,去累加這個結果。固然,也能夠考慮用spark等實時計算框架去處理,這種高深的技術,不在這次討論範圍內。(PS:主要是我也不懂)
程序的優化不少時候都是一些細節的問題,更應該注意平時的積累,阿里SQL的規範有不少能夠吸收的地方,以上也是本身工做中的一些總結,歡迎你們補充。
(完)
歡迎你們關注個人公衆號交流、學習、第一時間獲取最新的文章。
微信號:itmifen