Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用sqlalchemy从mysql获取海量数据的最佳方法是什么?_Python_Sqlalchemy - Fatal编程技术网

Python 使用sqlalchemy从mysql获取海量数据的最佳方法是什么?

Python 使用sqlalchemy从mysql获取海量数据的最佳方法是什么?,python,sqlalchemy,Python,Sqlalchemy,我想处理MySQL中存储的1000多万个数据。所以我写这篇文章是为了将sql分为几个部分,然后将数据连接到后面的过程中。如果count:last\u fetched\u id更改SQL而不修改代码,这样就可以了。谢谢

我想处理MySQL中存储的1000多万个数据。所以我写这篇文章是为了将sql分为几个部分,然后将数据连接到后面的过程中。如果
count<200万
,它工作得很好。然而,当
计数增加时,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

这是因为您使用的是
限制
/
偏移量
,因此当您指定偏移量3000000时,例如,数据库必须跳过3000000条记录


正确的方法是按某个索引列排序,例如主键
id
列,然后执行
WHERE id>:last\u fetched\u id

更改SQL而不修改代码,这样就可以了。谢谢