索引使用的限制條件,sql優化有哪些,數據同步問題(緩存和數據庫),緩存優化

索引使用的限制條件,sql優化有哪些,數據同步問題(緩存和數據庫),緩存優化

索引使用的限制條件,sql優化有哪些

a,選取最適用的字段:在創建表的時候,爲了獲得更好的性能,我們可以將表中字段的寬度設得儘可能小。另外一個提高效率的方法是在可能的情況下,應該儘量把字段設置爲NOTNULL,
b,使用連接(JOIN)來代替子查詢(Sub-Queries)
c,使用聯合(UNION)來代替手動創建的臨時表
d,事物:
1、要麼語句塊中每條語句都操作成功,要麼都失敗。換句話說,就是可以保持數據庫中數據的一致性和完整
性。事物以BEGIN關鍵字開始,COMMIT關鍵字結束。在這之間的一條SQL操作失敗,那麼,ROLLBACK命令就可以
把數據庫恢復到BEGIN開始之前的狀態。
2、 是當多個用戶同時使用相同的數據源時,它可以利用鎖定數據庫的方法來爲用戶提供一種安全的訪問方
式,這樣可以保證用戶的操作不被其它的用戶所幹擾。
e,減少表關聯,加入冗餘字段
f,使用外鍵:鎖定表的方法可以維護數據的完整性,但是它卻不能保證數據的關聯性。這個時候我們就可以使用外鍵。
g,使用索引
h,優化的查詢語句
i,集羣
j,讀寫分離
k,主從複製
l,分表
m,分庫
o,適當的時候可以使用存儲過程

限制:儘量用全職索引,最左前綴:查詢從索引的最左前列開始並且不跳過索引中的列;索引列上不操作,範圍之後全失效; 不等空值還有OR,索引影響要注意;like以通配符%開頭索引失效會變成全表掃描的操作,字符串不加單引號索引失效

數據同步問題(緩存和數據庫),緩存優化

1.降低後端負載:對於高消耗的SQL:join結果集、分組統計結果;對這些結果進行緩存。
2.加速請求響應
3.大量寫合併爲批量寫:如計數器先redis累加再批量寫入DB
4.超時剔除:例如expire
5.主動更新:開發控制生命週期(最終一致性,時間間隔比較短)
6.緩存空對象
7.布隆過濾器攔截
8.命令本身的效率:例如sql優化,命令優化
9.網絡次數:減少通信次數
10.降低接入成本:長連/連接池,NIO等。
11.IO訪問合併
目的:要減少緩存重建次數、數據儘可能一致、減少潛在危險。
解決方案:
1.互斥鎖setex,setnx:
如果 set(nx 和 ex) 結果爲 true,說明此時沒有其他線程重建緩存,那麼當前線程執行緩存構建邏輯。
如果 setnx(nx 和 ex) 結果爲 false,說明此時已經有其他線程正在執行構建緩存的工作,那麼當前線程將休息指定時間 ( 例如這裏是 50 毫秒,取決於構建緩存的速度 ) 後,重新執行函數,直到獲取到數據。

2永遠不過期:
熱點key,無非是併發特別大一級重建緩存時間比較長,如果直接設置過期時間,那麼時間到的時候,巨大的訪問量會壓迫到數據庫上,所以要給熱點key的val增加一個邏輯過期時間字段,併發訪問的時候,判斷這個邏輯字段的時間值是否大於當前時間,大於了說明要對緩存進行更新了,那麼這個時候,依然讓所有線程訪問老的緩存,因爲緩存並沒有設置過期,但是另開一個線程對緩存進行重構。等重構成功,即執行了redis set操作之後,所有的線程就可以訪問到重構後的緩存中的新的內容了

從緩存層面來看,確實沒有設置過期時間,所以不會出現熱點 key 過期後產生的問題,也就是“物理”不過期。
從功能層面來看,爲每個 value 設置一個邏輯過期時間,當發現超過邏輯過期時間後,會使用單獨的線程去構建緩存。

一致性問題:
1.先刪除緩存,然後在更新數據庫,如果刪除緩存失敗,那就不要更新數據庫,如果說刪除緩存成功,而更新數據庫失敗,那查詢的時候只是從數據庫裏查了舊的數據而已,這樣就能保持數據庫與緩存的一致性。
2.先去緩存裏看下有沒有數據,如果沒有,可以先去隊列裏看是否有相同數據在做更新,發現隊列裏有一個請求了,那麼就不要放新的操作進去了,用一個while(true)循環去查詢緩存,循環個200MS左右再次發送到隊列裏去,然後同步等待緩存更新完成

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章