背景:
对于数据的列表拉取响应变慢,数据需要从mysql迁移到es,从而数据从es进行读取;
解决思路:
由于数据量太大,需要每批从mysql进行数据查询进行导入到es;
方案一:
从mysql分页根据offset、limit进行查询
方案二:
由于方案一在测试过程中offset越大,查询的时间越长,在测试库中到50万条只有需要解决1s时间。
由于使用es过程中了解到,es查询可以使用 search after
,那么是否mysql这么使用也能提高查询效率呢?
使用这种方案明显查询效率得到了明显的提高
方案介绍:
方案一:
从mysql分页根据offset、limit进行查询
select
id,user_age,user_name
from message_test
ORDER BY id
limit #{offset} , #{limit}
自测环境刚开始时间 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万数据的时间,可以看出已经花了 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万条数据, 从mysql查询81万条数据,然后插入到es,总共花了10min 34s 678ms
2019-09-12 14:22:08.786 开始时间
2019-09-12 14:32:43.464 结束时间
方案二:
由于方案一在测试过程中offset越大,查询的时间越长,要是数据量越大,导致整个过程就会花费很多时间。
在使用es过程中了解到,es支持 search after,那么使用mysql查询数据学习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
可以看出后面数据的查询并不会收到影响
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万条数据,插入到es,总的时间花了1分53s时间。
14:42:37.071
14:44:30.651
使用这种方案明显查询效率得到了明显的提高
总结:
参考elasticsearch的设计,可以提升效率,节约不必要的开销;在以后设计一些中间件和业务代码的过程中可以借鉴其它中间件的好的技术方案,运用到自己的设计系统设计中;