Sto sviluppando un programma in Python che accede a un database MySQL usando MySQLdb. In determinate situazioni, devo eseguire un comando INSERT o REPLACE su molte righe. Attualmente sto facendo così:Perché eseguirlo lentamente in Python MySQLdb?
db.execute("REPLACE INTO " + table + " (" + ",".join(cols) + ") VALUES" +
",".join(["(" + ",".join(["%s"] * len(cols)) + ")"] * len(data)),
[row[col] for row in data for col in cols])
Funziona bene, ma è un po 'imbarazzante. Mi stavo chiedendo se potevo rendere più facile la lettura, e ho scoperto il comando executemany. Ho cambiato il mio codice in questo modo:
db.executemany("REPLACE INTO " + table + " (" + ",".join(cols) + ") " +
"VALUES(" + ",".join(["%s"] * len(cols)) + ")",
[tuple(row[col] for col in cols) for row in data])
Ha funzionato, ma ha funzionato molto più lentamente. Nei miei test, per insiemi di dati relativamente piccoli (circa 100-200 righe), ha funzionato circa 6 volte più lentamente. Per i big data set (circa 13.000 file, il più grande che mi aspetto di gestire), ha funzionato circa 50 volte più lentamente. Perché sta facendo questo?
Mi piacerebbe davvero semplificare il mio codice, ma non voglio il grande calo delle prestazioni. Qualcuno sa di un modo per renderlo più veloce?
Sto usando Python 2.7 e MySQLdb 1.2.3. Ho provato ad armeggiare con la funzione setinputsizes, ma non sembrava che facesse nulla. Ho guardato il codice sorgente MySQLdb e sembra che non dovrebbe fare nulla.
quante righe stai inserendo/sostituendo? la tua seconda affermazione crea un enorme elenco in memoria prima di inviarlo a mysql. – nosklo
Sto sostituendo fino a 13.000 righe. Non penso che la creazione della lista sia il collo di bottiglia. Se creo l'elenco ma non lo passo al cursore db, ci vuole appena un po 'di tempo. –
(Non risponderà alla domanda, ma ...) 'INSERIRE ... ON DUPLICATE KEY UPDATE ...' è quasi sempre meglio di 'REPLACE ...'. –