在oltp高併發 insert環境中,遞增列(時間,使用序列的主鍵列)的索引很容易引起索引熱點塊爭用。
遞增列的索引會一直不斷的往索引「最右邊」的葉子塊插入最新資料(因為索引預設公升序排序),在高併發insert的時候,一次只能由乙個session進行insert,其餘session會處於等待狀態,這樣就引起了索引熱點塊爭用。
對於遞增的主鍵列索引,可以對這個索引進行反轉(reverse),這樣在高併發insert的時候,就不會同時插入索引「最右邊」的葉子塊,而是會均衡的插入到各個不同的索引葉子塊中,這樣就解決了主鍵列索引的熱點塊問題。
將索引進行反轉之後,索引的集群因子會變得很大(基本上接近於表的總行數),此時索引範圍掃瞄 回表會有嚴重的效能問題,但是一般情況下,主鍵列都是等值訪問,索引走的是 index unique scan,索引唯一掃瞄 不受集群因子的影響,所以對主鍵列索引進行反轉沒有任何問題。
對於遞增的時間列索引,不能對這個索引進行反轉,因為時間欄位會經常進行範圍查詢,對時間欄位的索引反轉之後,索引的集群因子會變得很大,會嚴重影響回表效能,遇到這種情況,應該考慮對錶根據時間進行範圍分割槽,利用分割槽裁剪來提公升查詢效能而不是在時間字段建立索引來提公升效能。
在oltp高併發insert環境中,非遞增列索引(比如**號碼)一般不會引起索引熱點塊爭用。非遞增列的資料都是隨機的(**號碼),在高併發insert的時候,資料會隨機的插入到索引的各個葉子塊中,因此非遞增列索引不會引起索引熱點塊問題,但是如果索引太多會嚴重影響高併發insert的效能。
當只有1個會話進行insert,這時表中有1個塊會發生變化,有n個索引,就有n個索引葉子塊會發生變化(不考慮索引**的情況),假設有10個索引,那麼就有10個索引葉子塊發生變化。
如果有10個會話同時進行 insert,這時表中最多有10個塊會發生變化,索引中最多有100個塊會發生變化(10個session*10個索引)。在高併發的insert環境中,表中的索引越多,insert速度越慢。
對於高併發insert,一般是採用分庫分表,讀寫分離,和訊息佇列等技術來解決。
在olap環境中,沒有高併發insert的情況,一般是單程序做批量insert。單程序做批量insert,可以在遞增列上建立索引,因為是單程序,沒有併發,不會有索引熱點塊爭用,資料也是一直插入的索引中「最右邊」的葉子塊,因此遞增列索引對批量insert影響不會太大。單程序做批量insert,不能在非遞增列建立索引,因為批量insert幾乎會更新索引中所有的葉子塊,因此非遞增列索引對批量insert影響很大。
在olap環境中,事實(fact)表沒有主鍵,時間列一般也是分割槽字段,所以遞增列上面一般是沒有索引的,而**號碼等非遞增列往往又需要索引,為了提高批量insert的效率,可以在insert之前先禁止索引,等insert完成之後再重建索引。
Oracle 索引維護
一 索引的分析 根據oracle文件所描述,如下情況要考慮重建索引 1.analyze index your index name validate structure 2.查詢索引碎片 select name,del lf rows,lf rows,round del lf rows lf row...
Oracle 索引維護
一 索引的分析 根據oracle文件所描述,如下情況要考慮重建索引 1.analyze index your index name validate structure 2.查詢索引碎片 select name,del lf rows,lf rows,round del lf rows lf row...
Lucene索引維護 四
新增索引 test public void adddocument throws exception 2.1 刪除全部 test public void testindexdeleteall throws exception說明 將索引目錄的索引資訊全部刪除,直接徹底刪除,無法恢復。2.2 根據條件...