Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come velocizzare l'inserimento in blocco in MS SQL Server utilizzando pyodbc

Come notato in un commento a un'altra risposta, il BULK INSERT di T-SQL il comando funzionerà solo se il file da importare si trova sulla stessa macchina dell'istanza di SQL Server o si trova in un percorso di rete SMB/CIFS che l'istanza di SQL Server può leggere. Pertanto potrebbe non essere applicabile nel caso in cui il file di origine si trovi su un client remoto.

pyodbc 4.0.19 ha aggiunto una funzione Cursor#fast_executemany che potrebbe essere utile in tal caso. fast_executemany è "off" per impostazione predefinita e il seguente codice di test ...

cnxn = pyodbc.connect(conn_str, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("TRUNCATE TABLE fast_executemany_test")

sql = "INSERT INTO fast_executemany_test (txtcol) VALUES (?)"
params = [(f'txt{i:06d}',) for i in range(1000)]
t0 = time.time()
crsr.executemany(sql, params)
print(f'{time.time() - t0:.1f} seconds')

... ci sono voluti circa 22 secondi per l'esecuzione sulla mia macchina di prova. Semplicemente aggiungendo crsr.fast_executemany = True ...

cnxn = pyodbc.connect(conn_str, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("TRUNCATE TABLE fast_executemany_test")

crsr.fast_executemany = True  # new in pyodbc 4.0.19

sql = "INSERT INTO fast_executemany_test (txtcol) VALUES (?)"
params = [(f'txt{i:06d}',) for i in range(1000)]
t0 = time.time()
crsr.executemany(sql, params)
print(f'{time.time() - t0:.1f} seconds')

... ha ridotto il tempo di esecuzione a poco più di 1 secondo.