最近的工作实现了一个时序统计功能:需要从源表中按指定的顺序取数据,分组合并,插入到目标表中。源表数据量比较大,上千万行,显然不适合一次性取(如果是一次性脚本,也可以考虑在大内存的机器上,但是定时任务每次启动都要占用几十GB的内存太夸张了),需要分页查询。但是在最初的实现中,使用了封装好的分页库,一个简单的全表查询,纯粹依靠limit子句来限制结果集窗口,形成的SQL语句类似这样:select*fromAorderbyx,ylimit30000,10000其中,字段x和字段y有一个联合索引,每页返回10000条记录。结果很糟糕。每页返回需要40秒,这样的查询需要循环几千次,执行完需要半天时间。解决方法也很简单。使用自定义分页机制实现基于字段x过滤的分页:select*fromAwherex>30000orderbyx,ylimit10000注意:这里的30000只是一个例子。记下页面最后一项的x值,作为“x>?”的判断条件。在下一页。python+sqlalchemy的代码示例如下:PAGE_SIZE=10000last_x=0#这里假设x总是大于零的整数,如果不是,则初始化一个最小值whilelast_x==0orlen(records>0):#last_x==0这个条件相当于判断是否第一次循环。事实上,最好在这里有一个do...while语句。不幸的是,python没有records=A.query.filter(A.x>last_x).order_by(A.x,A.y).limit(PAGE_SIZE)last_x=records[-1].x#dosomething
