背景:
對于數(shù)據(jù)的列表拉取響應(yīng)變慢,數(shù)據(jù)需要從mysql遷移到es秆麸,從而數(shù)據(jù)從es進(jìn)行讀瘸踵凇;
解決思路:
由于數(shù)據(jù)量太大沮趣,需要每批從mysql進(jìn)行數(shù)據(jù)查詢進(jìn)行導(dǎo)入到es屯烦;
方案一:
從mysql分頁根據(jù)offset、limit進(jìn)行查詢
方案二:
由于方案一在測試過程中offset越大,查詢的時間越長驻龟,在測試庫中到50萬條只有需要解決1s時間温眉。
由于使用es過程中了解到,es查詢可以使用 search after
翁狐,那么是否mysql這么使用也能提高查詢效率呢类溢?
使用這種方案明顯查詢效率得到了明顯的提高
方案介紹:
方案一:
從mysql分頁根據(jù)offset、limit進(jìn)行查詢
select
id,user_age,user_name
from message_test
ORDER BY id
limit #{offset} , #{limit}
自測環(huán)境剛開始時間 14:22:08.786 --> 14:22:08.845 花了59ms 的時間
2019-09-12 14:22:08.786 [http-nio-7012-exec-10] DEBUG c.y.s.m.d.M.selectMysqlToES - ==> Preparing: select id,user_age,user_name from message_test ORDER BY id limit ? , ?
2019-09-12 14:22:08.786 [http-nio-7012-exec-10] DEBUG c.y.s.m.d.M.selectMysqlToES - ==> Parameters: 0(Long), 1000(Long)
2019-09-12 14:22:08.845 [http-nio-7012-exec-10] DEBUG c.y.s.m.d.M.selectMysqlToES - <== Total: 1000
到80萬數(shù)據(jù)的時間露懒,可以看出已經(jīng)花了 14:32:42.027->14:32:43.464 花了1437ms 的時間
2019-09-12 14:32:42.027 [http-nio-7012-exec-10] DEBUG c.y.s.m.d.M.selectMysqlToES - ==> Preparing: select id,user_age,user_name from message_test ORDER BY id limit ? , ?
2019-09-12 14:32:42.027 [http-nio-7012-exec-10] DEBUG c.y.s.m.d.M.selectMysqlToES - ==> Parameters: 816000(Long), 1000(Long)
2019-09-12 14:32:43.464 [http-nio-7012-exec-10] DEBUG c.y.s.m.d.M.selectMysqlToES - <== Total: 556
整個流程下來闯冷,同步81萬條數(shù)據(jù), 從mysql查詢81萬條數(shù)據(jù)懈词,然后插入到es蛇耀,總共花了10min 34s 678ms
2019-09-12 14:22:08.786 開始時間
2019-09-12 14:32:43.464 結(jié)束時間
方案二:
由于方案一在測試過程中offset越大,查詢的時間越長钦睡,要是數(shù)據(jù)量越大蒂窒,導(dǎo)致整個過程就會花費很多時間。
在使用es過程中了解到荞怒,es支持 search after洒琢,那么使用mysql查詢數(shù)據(jù)學(xué)習(xí)search after的思路
,提高查詢效率
select
id,user_age,user_name
from message_test
WHERE id > #{id}
ORDER BY id
limit #{limit}
第一次查詢的時候 14:42:37.071 --> 14:42:37.109 花了38 ms
14:42:37.071 [main] DEBUG c.y.s.m.d.M.selectMysqlToESSearchAfter - ==> Preparing: select id,user_age,user_name from message_test WHERE id > ? ORDER BY id limit ?
14:42:37.071 [main] DEBUG c.y.s.m.d.M.selectMysqlToESSearchAfter - ==> Parameters: 0(Long), 1000(Long)
14:42:37.109 [main] DEBUG c.y.s.m.d.M.selectMysqlToESSearchAfter - <== Total: 1000
最后一次查詢的時候 14:44:30.645 --> 14:44:30.651 花了6 ms
可以看出后面數(shù)據(jù)的查詢并不會收到影響
14:44:30.645 [main] DEBUG c.y.s.m.d.M.selectMysqlToESSearchAfter - ==> Preparing: select id,user_age,user_name from message_test WHERE id > ? ORDER BY id limit ?
14:44:30.645 [main] DEBUG c.y.s.m.d.M.selectMysqlToESSearchAfter - ==> Parameters: 3061952(Long), 1000(Long)
14:44:30.651 [main] DEBUG c.y.s.m.d.M.selectMysqlToESSearchAfter - <== Total: 426
總的時間褐桌, 查詢81萬條數(shù)據(jù)衰抑,插入到es,總的時間花了1分53s時間荧嵌。
14:42:37.071
14:44:30.651
使用這種方案明顯查詢效率得到了明顯的提高
總結(jié):
參考elasticsearch的設(shè)計呛踊,可以提升效率,節(jié)約不必要的開銷啦撮;在以后設(shè)計一些中間件和業(yè)務(wù)代碼的過程中可以借鑒其它中間件的好的技術(shù)方案谭网,運(yùn)用到自己的設(shè)計系統(tǒng)設(shè)計中;