Mengapa psycopg2 INSERT membutuhkan waktu lama untuk dijalankan dalam satu lingkaran dan bagaimana cara mempercepatnya?

Saya mencoba memasukkan baris (source_lat, source_long, tujuan_lat, tujuan_long) dari kerangka data Pandas ke dalam tabel PostgreSQL (gmaps) menggunakan psycopg2 INSERT dalam loop for. Tabel memiliki batasan integritas yang mencegah baris duplikat (source_lat, source_long, tujuan_lat, tujuan_long) disisipkan, jadi saya menangkap duplikat apa pun dengan blok coba kecuali. Kode saya ada di bawah.

Saya mengulangi setiap baris dalam kerangka data (sekitar 100.000 baris) dan memanggil kursor.execute(INSERT) pada setiap baris, melihat apakah itu menimbulkan kesalahan integritas, jika tidak, saya memasukkan baris itu ke tabel gmaps.

Namun, potongan kode ini membutuhkan waktu lama untuk dijalankan - bagaimana cara mempercepatnya? Saya tidak yakin di mana letak biaya overhead? Terima kasih!

Ele adalah tupel yang menampung (source_lat, source_long, tujuan_lat, tujuan_long)

for ele in coordinates:
#Inserts new row to table
      try:
         cursor.execute('INSERT INTO gmaps (source_latitude, source_longitude, destination_latitude, destination_longitude) VALUES (%s, %s, %s, %s)', (ele[0], ele[1], ele[2], ele[3])))
      except psycopg2.IntegrityError:
         conn.rollback()
      else:
         conn.commit()

person wanderingstu    schedule 02.08.2019    source sumber
comment
Ini bukan kode tetapi database menolak tindakan tersebut. Anda dapat mencoba apakah cepat ketika Anda langsung memasukkan nilai ke dalam database.   -  person Yuan    schedule 02.08.2019
comment
Mengeksekusi 100.000 pernyataan INSERT terpisah akan menjadi lambat. Tidak ada jalan lain.   -  person John Gordon    schedule 02.08.2019


Jawaban (1)


Ada beberapa opsi untuk mempercepat penyisipan data massal.

1.) commit() setelah perulangan selesai:

for ele in coordinates:
    cursor.execute('INSERT INTO gmaps (source_latitude, source_longitude, destination_latitude, destination_longitude) VALUES (%s, %s, %s, %s)', (ele[0], ele[1], ele[2], ele[3])))
conn.commit()

2.) Gunakan pembantu eksekusi cepat psycopg2, seperti execute_batch() or execute_values().

3.) Konsentrasi string menggunakan mogrify():

dataText = ','.join(cur.mogrify('(%s,%s,%s,%s)', row) for ele in coordinates)
cur.execute('INSERT INTO gmaps VALUES ' + dataText)
cur.commit()

Untuk perbandingan mendetail mengenai kecepatan eksekusi INSERT, lihat tolok ukur ini.

person Maurice Meyer    schedule 03.08.2019