当前位置: 首页 > 知识库问答 >
问题:

elasticsearch - mysql多结果集+覆盖索引无法满足需求的时候,有哪些优化sql的方式?什么时候会用到ES?

明松
2023-09-09

最初问题的背景是这样:

  • 例如对某个客户的报表生成需求,需要查询该客户在特定时间范围内的账单明细

为了简化说明,下面忽略连接查询,则可能的sql如下:

select out_trade_no, payer_id, amount, status, gmt_createfrom orderwhere merchant_id=123 and gmt_create between #{start} and #{end}order by gmt_create desc;

那么至少会需要一个(merchant_id, gmt_create)这样的一个多列索引。
此时因为要查询的字段比较多,所以不可能创建一个很长的多列索引来避免回表查询。而按照我的理解,这样的sql只能在二级索引上查到一条id就回表查询一次,如果gmt_create的范围拉的比较长(比如1个月),则会出现较多的随机IO。

一个能想到的可能优化是通过增加每页可以读取的数据来提高查询效率——延迟关联,那么将sql改为如下:

select o.out_trade_no, o.payer_id, o.amount, o.status, o.gmt_createfrom order as o    inner join (        select id from order        where merchant_id=123 and gmt_create between #{start} and #{end}    ) as sub using(id)order by o.gmt_create desc;

应该是可以进一步提高效率的。

不过最近我发现有些公司会直接使用ES来存储订单/明细表的数据,然后将类似这样的查询(例如报表需求)转发到es上执行,我想知道这样可以进一步提高查询效率吗?还是因为存在别的需求共同导致他们选择了es来代替这类sql查询?

共有1个答案

唐弘益
2023-09-09

灰机:@唯一丶 另外关于将mysql的订单数据同步到es的情况,我目前总结有两点可能:
商户侧和用户侧的查询订单操作比较多,传统的分库表、查询优化已无法满足,所以用es分担mysql的读压力
有较多且复杂的聚合计算类需求,放到es上执行优势更明显
不知道这两点是否有问题,或者还有补充。
今天 12:13
来自北京
唯一丶:@灰机 我们使用的主要原因也是因为 ES 的查询、聚合更加强大,能较大限度的满足我们的需要,且不用过于的去考虑优化。
对于简单化的查询,仍然是在数据库进行,只是后台运营需要的复杂查询和统计才会放到 ES 端查询。

 类似资料:
  • 问题内容: 如果我有 如果我比较A的2个实例但没有覆盖equals方法,是否可以获得预期的结果? 问题答案: 如果我比较A的2个实例但没有覆盖equals方法,是否可以获得预期的结果? 这取决于您的期望:) 默认实现将为您提供 引用相等性-换句话说,当您比较两个引用时,仅当它们是对同一对象的引用时才返回true。 通常,您将重写以实现“值相等”,在这种情况下,两个不同的对象通常被认为具有相等的字段

  • 问题内容: 当我创建自己的Android自定义类时,它就是本机类。然后,当我要重写基方法,我总是叫方法,就像我一直做的,等 我认为就是这样,因为从一开始,Android团队就建议我们始终调用每个方法重写。 但是,在 许多书籍中, 我可以看到比我自己更有经验的开发人员经常忽略调用,而且我真的怀疑他们是因为缺乏知识而这样做。例如,看看这个基本的SAX,其中解析器类中被省略,并且: 如果尝试通过Ecli

  • 问题内容: 我阅读的所有资料都提到了几个案例,并以“其他一些案例”作了总结。在视图/活动中调用onSaveInstanceState方法时,所有情况是什么? 问题答案: 该文档称 在活动被杀死之前将调用此方法,以便将来在将来返回某个时间时可以恢复其状态。

  • 问题内容: 我对JAX-WS进行了概述,并注意到了(和)的一些引用。 在什么情况下需要?(我认为JSR 109服务器?!) 问题答案: 是使用SUN的参考实现将Web服务作为标准存档部署在非Java EE5 Servlet容器上时所需的专有部署描述符。 Sun的RI 用作servlet上下文事件的侦听器和调度程序servlet。两者都必须在中声明。然后需要该文件为定义Web服务端点,以使其知道必须

  • 自己写的service可以调basemapper也可以掉mybatis-plus中的service,有没有统一的规则?