理論:第三章:索引使用的限制條件,sql優(yōu)化有哪些,數(shù)據(jù)同步問題(緩存和數(shù)據(jù)庫),緩存優(yōu)化

索引使用的限制條件,sql優(yōu)化有哪些

    a,選取最適用的字段:在創(chuàng)建表的時候,為了獲得更好的性能,我們可以將表中字段的寬度設得盡可能小。另外一
    個提高效率的方法是在可能的情況下,應該盡量把字段設置為NOTNULL,
    b,使用連接(JOIN)來代替子查詢(Sub-Queries)
    c,使用聯(lián)合(UNION)來代替手動創(chuàng)建的臨時表
    d,事物:
        a)要么語句塊中每條語句都操作成功,要么都失敗。換句話說,就是可以保持數(shù)據(jù)庫中數(shù)據(jù)的一致性和完整
    性。事物以BEGIN關鍵字開始,COMMIT關鍵字結束。在這之間的一條SQL操作失敗,那么,ROLLBACK命令就可以
    把數(shù)據(jù)庫恢復到BEGIN開始之前的狀態(tài)。
        b) 是當多個用戶同時使用相同的數(shù)據(jù)源時,它可以利用鎖定數(shù)據(jù)庫的方法來為用戶提供一種安全的訪問方
    式,這樣可以保證用戶的操作不被其它的用戶所干擾。
    e,減少表關聯(lián),加入冗余字段
    f,使用外鍵:鎖定表的方法可以維護數(shù)據(jù)的完整性,但是它卻不能保證數(shù)據(jù)的關聯(lián)性。這個時候我們就可以使用外鍵。
    g,使用索引
    h,優(yōu)化的查詢語句
    i,集群
    j,讀寫分離
    k,主從復制
    l,分表
    m,分庫
    o,適當?shù)臅r候可以使用存儲過程
     
    限制:盡量用全職索引,最左前綴:查詢從索引的最左前列開始并且不跳過索引中的列;索引列上不操作,范圍之
    后全失效; 不等空值還有OR,索引影響要注意;like以通配符%開頭索引失效會變成全表掃描的操作,字符串不
    加單引號索引失效

數(shù)據(jù)同步問題(緩存和數(shù)據(jù)庫),緩存優(yōu)化

    1.降低后端負載:對于高消耗的SQL:join結果集、分組統(tǒng)計結果;對這些結果進行緩存。
    2.加速請求響應
    3.大量寫合并為批量寫:如計數(shù)器先redis累加再批量寫入DB
    4.超時剔除:例如expire
    5.主動更新:開發(fā)控制生命周期(最終一致性,時間間隔比較短)
    6.緩存空對象
    7.布隆過濾器攔截
    8.命令本身的效率:例如sql優(yōu)化,命令優(yōu)化
    9.網(wǎng)絡次數(shù):減少通信次數(shù)
    10.降低接入成本:長連/連接池,NIO等。
    11.IO訪問合并
    目的:要減少緩存重建次數(shù)、數(shù)據(jù)盡可能一致、減少潛在危險。
    解決方案:
    1.互斥鎖setex,setnx:
    如果 set(nx 和 ex) 結果為 true,說明此時沒有其他線程重建緩存,那么當前線程執(zhí)行緩存構建邏輯。
    如果 setnx(nx 和 ex) 結果為 false,說明此時已經有其他線程正在執(zhí)行構建緩存的工作,那么當前線程將休
    息指定時間 ( 例如這里是 50 毫秒,取決于構建緩存的速度 ) 后,重新執(zhí)行函數(shù),直到獲取到數(shù)據(jù)。
     
    2永遠不過期:
    熱點key,無非是并發(fā)特別大一級重建緩存時間比較長,如果直接設置過期時間,那么時間到的時候,巨大的訪
    問量會壓迫到數(shù)據(jù)庫上,所以要給熱點key的val增加一個邏輯過期時間字段,并發(fā)訪問的時候,判斷這個邏輯
    字段的時間值是否大于當前時間,大于了說明要對緩存進行更新了,那么這個時候,依然讓所有線程訪問老的
    緩存,因為緩存并沒有設置過期,但是另開一個線程對緩存進行重構。等重構成功,即執(zhí)行了redis set操作
    之后,所有的線程就可以訪問到重構后的緩存中的新的內容了
     
    從緩存層面來看,確實沒有設置過期時間,所以不會出現(xiàn)熱點 key 過期后產生的問題,也就是“物理”不過期。
    從功能層面來看,為每個 value 設置一個邏輯過期時間,當發(fā)現(xiàn)超過邏輯過期時間后,會使用單獨的線程去構建緩存。
     
    一致性問題:
    1.先刪除緩存,然后在更新數(shù)據(jù)庫,如果刪除緩存失敗,那就不要更新數(shù)據(jù)庫,如果說刪除緩存成功,而更新
    數(shù)據(jù)庫失敗,那查詢的時候只是從數(shù)據(jù)庫里查了舊的數(shù)據(jù)而已,這樣就能保持數(shù)據(jù)庫與緩存的一致性。
    2.先去緩存里看下有沒有數(shù)據(jù),如果沒有,可以先去隊列里看是否有相同數(shù)據(jù)在做更新,發(fā)現(xiàn)隊列里有一個請
    求了,那么就不要放新的操作進去了,用一個while(true)循環(huán)去查詢緩存,循環(huán)個200MS左右再次發(fā)送到
    隊列里去,然后同步等待緩存更新完成。