Optimization of MySQL IN

Scene description:

The problem with MySQL's IN: due to the huge content of in (5000+), the query efficiency is low (more than 4 seconds)

SELECT * FROM xxx WHERE `id` IN(xxx)

Planned solution:

1.测试得到IN里面的最佳数量
2.循环分多次查询
3.多线程共同执行

Actual test record:

1. Query the best quantity

1次    4265ms、4177ms、4112ms		        平均4.18秒	 5643条
2次    1128ms、1105ms、1117ms			    平均2.23秒	 2822条
3次    326ms、298ms、326ms			        平均1.27秒	 1411条
8次    117ms、91ms、88ms、100ms、86ms         平均0.77秒    705条
20次   43 32 24 25 34 23 24 27 28 22	    平均0.56秒     282条
40次   25 16 11 10 13 10 10 10 13 10 	    平均0.51秒     141条
30次   29 18 17 13 14 15 15 17 15 17	    平均0.51秒     188条

in conclusion:

20次和40次差距不大,又测试了30次的数据结果,结果和40次一样。
mysql查询次数对性能也有影响,所以我们以200条定为最佳数量值进行测试.

2. Loop query (29 times)

    Integer total = orderIds.size();
    Integer size = 200;
    Integer pages = total % size == 0 ? total / size : total / size + 1;
    List<Order> finalRes = new ArrayList<Order>(total);
    for (int i = 0; i < pages; i++) {
        Integer toIndex = (i + 1) * size > total ? total : (i + 1) * size;
        //分批查询
        List<Order> orderList = orderMapper.selectList(new EntityWrapper<Order>().in("id", orderIds.subList(i * size, toIndex)));
        //组装结果
        finalRes.addAll(orderList);
    }

operation result:

455ms、451ms、450ms     平均时间:0.45秒

3. Multithreading (12 cores)

Integer size = 200;
Integer total = orders.size();
Integer pages = total % size == 0 ? total / size : total / size + 1;

//线程池
ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

List<InOrderIds> callables = new ArrayList<>();
for (int i = 0; i < pages; i++) {
    Integer toIndex = (i + 1) * size > total ? total : (i + 1) * size;
    callables.add(new InOrderIds(orderIds.subList(i * size, toIndex), i));
}
List<Future<List<Order>>> futures = service.invokeAll(callables);
List<Order> finalRes = new ArrayList<Order>(total);
futures.forEach((f) -> {
    try {
        System.out.println(finalRes.addAll(f.get()));
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
});
service.shutDown();//释放资源

operation result:

单核CPU      256ms、225ms、252ms   平均时间:0.244秒
多核(12)CPU    76ms、42ms、72ms   平均时间:0.063秒
final conclusion:
IN里面最多200条达到性能瓶颈;
循环查询能提升近8-9倍的效率;
多线程是性能最好的,建议使用。

Insert picture description here

Published 41 original articles · Liked 14 · Visitors 10,000+

Guess you like

Origin blog.csdn.net/Yunwei_Zheng/article/details/104017292