2016-10-09 3 views
1

Ich möchte über 10 Millionen in MySQL gespeicherte Daten verarbeiten. Also habe ich das geschrieben, um die sql in mehrere Teile zu zerlegen und dann die Daten für den späteren Prozess zu verketten. Es funktioniert gut, wenn count < 2 millions. Allerdings, wenn die count steigen, die Zeit, die sqlalchemy konsumiert, geht viel länger.Was ist der beste Weg, um riesige Daten von MySQL mit sqlalchemy zu holen?

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() 

Die Frage ist, warum die sqlalchemy immer mehr Zeit in Anspruch nehmen (ich Zeit unter angemeldet und Post), und was ist der beste Weg, um mit dieser Situation umgehen?

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 

Antwort

1

Dies ist weil Sie LIMIT/OFFSET verwenden. Wenn Sie beispielsweise den Offset 3000000 angeben, muss die Datenbank mehr als 3000000 Datensätze überspringen.

Der richtige Weg, dies zu tun ist ORDER BY einige indexierte Spalte, wie der Primärschlüssel id Spalte, zum Beispiel, dann tun Sie eine WHERE id > :last_fetched_id.

+0

Ich ändere die SQL, ohne den Code zu ändern, und es funktioniert. Vielen Dank! – chingi

Verwandte Themen