問題描述
????近期在做資料同步功能,各模塊資料經過 AOP 攔截,形成insert、update、delete陳述句,統一進入Kafka,然后由消費端取出消費到Oracle,
????但在消費程序中發現,insert一條平均耗時 4 ms, 但更新一條資料平均耗時12s,尤其在更新3、4千萬的大表時,可達到30多秒,洗掉也慢,導致消費堆積,
sql陳述句如下
新增 INSERT INTO TEST(ID,NAME,AGE,TIME) VALUES ('4089480E7212C8B4017292D62A49000D','張三','32',sysdate);
修改 UPDATE TEST SET NAME='李四',AGE='45' WHERE ID = '4089480E7212C8B4017292D62A49000D';
洗掉 DELETE FROM TEST WHERE ID = '4089480E7212C8B4017292D62A49000D';
問題分析
????經過查看sql執行計劃,判斷問題出在,update和delete陳述句中的
where id = ‘4089480E7212C8B4017292D62A49000D’
????因為我們表的主鍵ID采用 RAW(16) 型別,資料庫存盤的都是二進制,索引自然也是建立在二進制資料基礎上,直接用 id = ‘4089480E7212C8B4017292D62A49000D’,相當于使用這個字串去資料庫中與所有id字串比對,無法利用到索引,從而導致update和delete很慢,
解決方法
????使用Oracle中自帶的 hextoraw 函式,如
UPDATE TEST SET NAME='李四',AGE='45' WHERE ID = hextoraw('4089480E7212C8B4017292D62A49000D');
????hextoraw 函式是將十六進制轉為二進制,因為資料庫存的就是二進制,索引也是在二進制資料上建立的,所以where條件根據id查找會走索引,update和delete慢的問題也得到解決,
????經過測驗,
select * from test where id = '4089480E7212C8B4017292D62A49000D'
耗時20s
select * from test where id = hextoraw('4089480E7212C8B4017292D62A49000D')
耗時0.12s
總結
????所以在分析sql陳述句執行時,優先考慮是否有索引,查詢是否走索引,
????如果 id 使用 自增 或者 字符型別 ,就不存在這個問題了,直接比對即可,
????由于專案運行好長時間了,最開始設計用的UUID當主鍵,類似的 sql 有很多,隨著資料量的不斷累積,查詢效率大受影響,接下來要好好修改一番了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/163608.html
標籤:Java
