趕集網dba石展分享歸納

王滔發表於2013-12-26

欄位不要使用null值。查詢,索引方面不利。
如果是整型,int,僅僅是設定 not null還不夠。最好是這種一個預設的值0。為什麼?

text型別處理效能低於varchar。
儘量不要使用text/blog資料型別,使用的話。拆分到單獨的表中儲存。

與阿里巴巴一個思想:大容量的資料不要存到資料庫中去,比如圖片,url。


將字元儲存轉換為數字儲存。比如ip用int儲存。
為什麼字元型資料建立索引,索引的名稱要建立字首:idx_pinyin
是考慮字母的區分度嗎?字母越長越容易區分?

它們習慣建立索引的命名規則是:idx_欄位名。


拒絕大SQL,拆解成多條簡單SQL。對於高併發的情況下,非常有利,避免一條複雜的sql語句把表鎖死。
由於一條sql只能在一個cpu中計算,那麼最好是做簡單的sql,可以減輕cpu負擔。

簡單sql的快取命中率更高。

多條sql合併成一條複雜的sql一步解決的思路,是傳統的思想。對於網際網路高併發,要求高效能的情況下,不適合。
思想:把複雜的東西拆分成小步驟。一個一個做。一次性去做複雜的。耗費很多時間。


儘量少用外來鍵,儘量少用儲存過程。少用觸發器。
減少使用mysql函式對結果進行處理。

作者也是強調,需要多少欄位就用多少欄位。

將or改為in。in的效率要更高。建議n數量小於200。不同的欄位進行or查詢的時候。比如 "a=x or b=y"將or可以修改成union,
where a=x union b=y。同一個欄位做成in比較好。in(1,2,3)。不同欄位沒辦法。




聯想起一道題目,將or中的順序指定。是不是使用in就解決了?


select catid from jay_category where catid=1 or catid=6 or catid=4
無解。or 預設是按照id,從小到大列出的。


實時統計:用memcache,雙向更新,凌晨跑基準。
非實時統計:儘量用單獨統計表,定期重算


把join連線查詢,拆分成單條sql語句,分多不操作。效能要高。可以減少大併發情況下鎖表。

作者告知,remark=115127 與 remark="115127"的查詢效能是有區別的。使用引號速度更快。不知道什麼原因。


批量匯入資料方面:
儘量不要使用INSERT ... SELECT延遲同步出錯。複製可能出現異常情況。
成批插入比當行插入更快,所以:insert values,values的速度要比拆分成多條
插入語句速度要快。符合成批載入資料比單行載入資料要快。
可以考慮大資料載入的時候用load data

大一點的公司。程式設計師編寫的每條sql都會經過dba進行分析確認,這樣保證效能。
dba畢竟是專業的資料庫人員。對於資料庫的原理,查詢效能優化有豐富的經驗。

一個單表,資料量在500萬-1000萬的時候就要考慮分表。所以使用bigint是沒有多少實際一樣的。

int(10) 與int(1)所儲存的資料額度其實是一樣的。後面的10表示是寬度。就是每個值儲存的時候佔用多少個位數。


他的思維:從儲存空間角度去考慮。儲存空間越少。對效能影響越好。

在傳統的資料庫系統中,是建議,儘量使用更少是sql完成更多是事情。也就是儘量少到使用一條sql實現查詢
但是在mysql中就不適合,因為mysql被設計成適合高效的連線和斷開,響應查詢。所以很適合拆分成多條sql去實現。
假設一個情況:在5000個qps中(每秒響應5000個sql請求),如果一條sql查詢超過了一秒,就會導致整個拖慢,就像現實生活中,堵車,只要其中一輛車拋錨了,就會導致所有的車都無法前進,被卡死了。本身道路寬度就有限。

有個思想:現實生活中,堵車,道路寬度有限。如果單純依靠擴寬道路來解決交通問題,是解決不了根源問題的,因為道路寬度即便擴寬,也有更多車去擁擠,擴寬是有極限,擴到不能擴了才麻煩。應該是一種排程思想。


資料庫的連線:即用即關掉。馬上關掉。即便是後面程式碼需要用到,也可以馬上關掉,然後再次連線
發帖:資料先insert into入表。然後圖片要傳入圖片系統。他建議是insert資料後。要關掉資料庫連線。這樣子可以避免一個問題:如果圖片系統出現問題。資料庫連線一直沒關掉,就會導致大量sleep等待。


永遠不要用程式對資料庫顯式的加鎖。加鎖是方便。但是會造成一些不可控的問題:把海豚綁死了。它怎麼跑得快?
除錯和排查問題很難(很難找到是那段程式加了鎖,php執行的時候是一個程式碼副本)。高併發情況下很危險。


如果涉及到需要鎖定的,使用事務機制,相對值修改、commit前二次校驗衝突。

表的欄位數控制在20-50個欄位。50個純int欄位。20個char欄位。計算方式:
硬碟3秒以上

單表的體積控制在1g。char型別大約是500萬行資料
1g/500萬=200個位元組 20個欄位
1g/1000萬


他們會把left join查詢拆分成多次去獲取資料。a left join b 先從a表獲取where條件的資料,然後又去b表聚合(這個時候就釋放了對a表的鎖)

相關文章