最初问题的背景是这样: * 例如对某个客户的报表生成需求,需要查询该客户在特定时间范围内的账单明细 为了简化说明,下面忽略连接查询,则可能的sql如下: select out_trade_no, payer_id, amount, status, gmt_create from order where 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_create from 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查询?