**1\. MySQL的binlog有有幾種錄入格式?分別有什么區別?**
有三種格式,statement,row和mixed.
statement模式下,記錄單元為語句.即每一個sql造成的影響會記錄.由于sql的執行是有上下文的,因此在保存的時候需要保存相關的信息,同時還有一些使用了函數之類的語句無法被記錄復制.
row級別下,記錄單元為每一行的改動,基本是可以全部記下來但是由于很多操作,會導致大量行的改動(比如alter table),因此這種模式的文件保存的信息太多,日志量太大.
mixed. 一種折中的方案,普通操作使用statement記錄,當無法使用statement的時候使用row.
此外,新版的MySQL中對row級別也做了一些優化,當表結構發生變化的時候,會記錄語句而不是逐行記錄.
*****
**2\. 超大分頁怎么處理?**
超大的分頁一般從兩個方向上來解決.
數據庫層面,這也是我們主要集中關注的(雖然收效沒那么大),類似于select \* from table where age > 20 limit 1000000,10這種查詢其實也是有可以優化的余地的. 這條語句需要load1000000數據然后基本上全部丟棄,只取10條當然比較慢. 當時我們可以修改為select \* from table where id in (select id from table where age > 20 limit 1000000,10).這樣雖然也load了一百萬的數據,但是由于索引覆蓋,要查詢的所有字段都在索引中,所以速度會很快. 同時如果ID連續的好,我們還可以select \* from table where id > 1000000 limit 10,效率也是不錯的,優化的可能性有許多種,但是核心思想都一樣,就是減少load的數據.
從需求的角度減少這種請求….主要是不做類似的需求(直接跳轉到幾百萬頁之后的具體某一頁.只允許逐頁查看或者按照給定的路線走,這樣可預測,可緩存)以及防止ID泄漏且連續被人惡意攻擊.
解決超大分頁,其實主要是靠緩存,可預測性的提前查到內容,緩存至redis等k-V數據庫中,直接返回即可.
在阿里巴巴《Java開發手冊》中,對超大分頁的解決辦法是類似于上面提到的第一種.
*****
**3\. 關心過業務系統里面的sql耗時嗎?統計過慢查詢嗎?對慢查詢都怎么優化過?**
在業務系統中,除了使用主鍵進行的查詢,其他的我都會在測試庫上測試其耗時,慢查詢的統計主要由運維在做,會定期將業務中的慢查詢反饋給我們.
慢查詢的優化首先要搞明白慢的原因是什么? 是查詢條件沒有命中索引?是load了不需要的數據列?還是數據量太大?
所以優化也是針對這三個方向來的,
首先分析語句,看看是否load了額外的數據,可能是查詢了多余的行并且拋棄掉了,可能是加載了許多結果中并不需要的列,對語句進行分析以及重寫.
分析語句的執行計劃,然后獲得其使用索引的情況,之后修改語句或者修改索引,使得語句可以盡可能的命中索引.
如果對語句的優化已經無法進行,可以考慮表中的數據量是否太大,如果是的話可以進行橫向或者縱向的分表.
關聯查詢中,小表驅大表,order排序選小表,否則產生臨時表(sql優化的一些方式)
*****
**4\. 上面提到橫向分表和縱向分表,可以分別舉一個適合他們的例子嗎?**
橫向分表是按行分表.假設我們有一張用戶表,主鍵是自增ID且同時是用戶的ID.數據量較大,有1億多條,那么此時放在一張表里的查詢效果就不太理想.我們可以根據主鍵ID進行分表,無論是按尾號分,或者按ID的區間分都是可以的. 假設按照尾號0-99分為100個表,那么每張表中的數據就僅有100w.這時的查詢效率無疑是可以滿足要求的.
縱向分表是按列分表.假設我們現在有一張文章表.包含字段id-摘要-內容.而系統中的展示形式是刷新出一個列表,列表中僅包含標題和摘要,當用戶點擊某篇文章進入詳情時才需要正文內容.此時,如果數據量大,將內容這個很大且不經常使用的列放在一起會拖慢原表的查詢速度.我們可以將上面的表分為兩張.id-摘要,id-內容.當用戶點擊詳情,那主鍵再來取一次內容即可.而增加的存儲量只是很小的主鍵字段.代價很小.
當然,分表其實和業務的關聯度很高,在分表之前一定要做好調研以及benchmark.不要按照自己的猜想盲目操作.
*****
**5\. 什么是存儲過程?有哪些優缺點?**
存儲過程是一些預編譯的SQL語句。1、更加直白的理解:存儲過程可以說是一個記錄集,它是由一些T-SQL語句組成的代碼塊,這些T-SQL語句代碼像一個方法一樣實現一些功能(對單表或多表的增刪改查),然后再給這個代碼塊取一個名字,在用到這個功能的時候調用他就行了。2、存儲過程是一個預編譯的代碼塊,執行效率比較高,一個存儲過程替代大量T\_SQL語句 ,可以降低網絡通信量,提高通信速率,可以一定程度上確保數據安全
但是,在互聯網項目中,其實是不太推薦存儲過程的,比較出名的就是阿里的《Java開發手冊》中禁止使用存儲過程,我個人的理解是,在互聯網項目中,迭代太快,項目的生命周期也比較短,人員流動相比于傳統的項目也更加頻繁,在這樣的情況下,存儲過程的管理確實是沒有那么方便,同時,復用性也沒有寫在服務層那么好.