假设你说的用户,不是开发人员,是终端用户,比如saas之类的系统用户。

如果对于用户是透明的,意味着每个用户只需要看到自己的数据,那么比较经济的处理方式是,把用户id的哈希值作为分配的条件,这样能够保证每个用户的数据都在同一个分配上。当用户的请求过来,只需要查询这个分配,就能像正常的单库单表一样的处理分页方式了。

but,分页也可以说两句,简单的情况就是top,rownum,limit这些常规方式。但是如果数据量非常大的情况下,比如查询10567页的100条数据,这就需要先根据where的过滤条件翻过去1056700条记录,慢成狗。但是我们细想一下,这么多记录,用户为什么神特么的需要看这么一百万记录。。。其实就是我们自己想多了,压根不可能有这种需求。怎么办?要么改需求,搞个热数据,归档数据,把24h的数据存起来,其他的数据归档掉,不让用户查

要么不提供精确分页,只让用户点击上一页,下一页,每次请求分页的时候,不带页码,只带最近的一个id,比如当前页最后一个数据的id=1056700,点击了下一页,就获取,select * from tablexxx where id>1056700 limit 100,这样mysql就不用先去从索引数出来一百万个数据(如果是select * from tablexxx limit 1056700,100),然后再去拿100个。能快的飞起。

很多时候,从用户角度思考问题,比技术角度好得多。

如果题主说的一个“用户”指的是用你这个分片中间件开发人员,他非要不按用户id来分片,这样就涉及到多个分片的数据聚合以后再取1056700个记录后的第100个。笨办法,没有:上面这个极端例子,多路查询,归并聚合,已经不现实了。。。

好办法1:用canal之类的同步一个异构的读从库,这个库按用户维度来分片,或者不分片。

好办法2:把数据同步到solr或elastic-search里去,做搜索。。。。。最推荐,非常快。