我想处理存储在MySQL中的超过1000万个数据。所以我写了这个来将sql分成几个部分然后连接后一个进程的数据。如果count < 2 millions
,它的效果很好。然而,当count
上升时,sqlalchemy消耗的时间会更长。
def fetch_from_sql(_sql_pat, count):
"""
:param _sql_pat: SELECT id, data FROM a.b LIMIT {},{};
:param count: how many data you want to fetch from mysql
:return: generator
"""
def gen_connect(sql):
__engine = create_engine(db_config['SQLALCHEMY_DATABASE_URI'])
with __engine.connect() as c:
for row in c.execute(sql)
yield row
def gen_range(limit, step):
if step > limit:
yield 0, limit
else:
R = range(0, limit + 1, step)
for idx, v in enumerate(R):
if idx == 0:
yield v, step
elif limit - v >= step:
yield v + 1, step
else:
yield v + 1, limit - v
sqls = [_sql_pat.format(start, step) for start, step in gen_range(count, 100000)]
sources = (gen_connect(sql) for sql in sqls)
for s in sources:
for item in s:
yield item
gc.collect()
问题是sqlalchemy花费越来越多时间的原因(我在下面记录时间和帖子),以及处理这种情况的最佳方法是什么?
Dumped 10000 items, at 2016-10-08 11:55:33
Dumped 1000000 items, at 2016-10-08 11:59:23
Dumped 2000000 items, at 2016-10-08 12:05:07
Dumped 3000000 items, at 2016-10-08 13:54:05
答案 0 :(得分:1)
这是因为您正在使用LIMIT
/ OFFSET
,因此当您指定偏移量3000000时,数据库必须跳过超过3000000条记录。
执行此操作的正确方法是ORDER BY
某个索引列,例如主键id
列,然后执行WHERE id > :last_fetched_id
。