分布式Solr的排序和分页使用下面的算法:
1. 传入查询条件q,排序sort,开始行数start,返回记录数rows
2. 修改参数,向各个分片shard发送新的查询请求:
a)保持q和sort不变
b)修改start=0,rows=原start+原rows
c)分片shard将会返回最多(原start+原rows)行数据,并且是按照sort排序的
3. 合并每个shard返回的数据,并按sort排序
4. 截取[原start,原start+原rows-1]行数据,返回给前端
上面的算法中,shard每次都返回[0,原start+原rows-1]行数据,导致shard的IO开销特别大。
我们比较前端需要第n页和第n+1页的变化,可以知道:
第n+1页的数据中包含了第n页的数据,所以在剔除后,新的第n+1页数据的传输量就会显著下降。
算法改进:
0. 假设分页始终是递增的,即取第n页之后,才取第n+1页
1. 传入查询条件q,排序sort,开始行数start,返回记录数rows
2. 修改参数,向各个分片shard发送新的查询请求:
a)保持q和sort不变
b)获取该shard保留的上次最大序号ID,如果没有,则设为-1
c)修改start=ID+1,rows=原start+原rows-ID-1
d)分片shard将会返回最多(原start+原rows-ID-1)行数据,并且是按照sort排序的
e)分片shard在结果集中返回shard名称
3. 合并每个shard返回的数据,并按sort排序
a)先按sort排序,再按shard排序
b)数据格式:shard,sort,id,序号,...
4. 截取[原start,原start+原rows-1]行数据,返回给前端
a)按照shard,分组统计截取的数据
b)更新每个shard保留的最大序号ID
1. 传入查询条件q,排序sort,开始行数start,返回记录数rows
2. 修改参数,向各个分片shard发送新的查询请求:
a)保持q和sort不变
b)修改start=0,rows=原start+原rows
c)分片shard将会返回最多(原start+原rows)行数据,并且是按照sort排序的
3. 合并每个shard返回的数据,并按sort排序
4. 截取[原start,原start+原rows-1]行数据,返回给前端
上面的算法中,shard每次都返回[0,原start+原rows-1]行数据,导致shard的IO开销特别大。
我们比较前端需要第n页和第n+1页的变化,可以知道:
第n+1页的数据中包含了第n页的数据,所以在剔除后,新的第n+1页数据的传输量就会显著下降。
算法改进:
0. 假设分页始终是递增的,即取第n页之后,才取第n+1页
1. 传入查询条件q,排序sort,开始行数start,返回记录数rows
2. 修改参数,向各个分片shard发送新的查询请求:
a)保持q和sort不变
b)获取该shard保留的上次最大序号ID,如果没有,则设为-1
c)修改start=ID+1,rows=原start+原rows-ID-1
d)分片shard将会返回最多(原start+原rows-ID-1)行数据,并且是按照sort排序的
e)分片shard在结果集中返回shard名称
3. 合并每个shard返回的数据,并按sort排序
a)先按sort排序,再按shard排序
b)数据格式:shard,sort,id,序号,...
4. 截取[原start,原start+原rows-1]行数据,返回给前端
a)按照shard,分组统计截取的数据
b)更新每个shard保留的最大序号ID