เหตุใด psycopg2 INSERT จึงใช้เวลานานมากในการวนซ้ำ และฉันจะเร่งความเร็วได้อย่างไร

ฉันกำลังพยายามแทรกแถว (source_lat, source_long, Destination_lat, Destination_long) จาก Pandas dataframe ลงในตาราง PostgreSQL (gmaps) โดยใช้ psycopg2 INSERT ใน for loop ตารางมีข้อจำกัดด้านความสมบูรณ์ที่ป้องกันการแทรกแถวที่ซ้ำกัน (source_lat, source_long, Destination_lat, Destination_long) ดังนั้นฉันจึงจับรายการที่ซ้ำกันด้วยการลองยกเว้นบล็อก รหัสของฉันอยู่ด้านล่าง

ฉันกำลังวนซ้ำทุกแถวใน dataframe (ประมาณ 100,000 แถว) และเรียก cursor.execute(INSERT) ในแต่ละแถว ดูว่านั่นทำให้เกิดข้อผิดพลาดด้านความสมบูรณ์หรือไม่ หากไม่เป็นเช่นนั้น ฉันจะแทรกแถวนั้นในตาราง gmaps

อย่างไรก็ตาม โค้ดชิ้นนี้ใช้เวลาทำงานตลอดไป - ฉันจะเร่งความเร็วได้อย่างไร ฉันไม่แน่ใจว่าค่าโสหุ้ยอยู่ที่ไหน? ขอบคุณ!

Ele เป็นสิ่งทูเพิลที่เก็บ (source_lat, source_long, Destination_lat, Destination_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 แหล่งที่มา
comment
ไม่ใช่รหัส แต่ฐานข้อมูลปฏิเสธการดำเนินการ คุณสามารถลองใช้งานได้เร็วหรือไม่เมื่อคุณใส่ค่าลงในฐานข้อมูลโดยตรง   -  person Yuan    schedule 02.08.2019
comment
การดำเนินการคำสั่ง INSERT แยกกัน 100,000 รายการจะดำเนินการได้ช้า ไม่มีทางรอบมัน   -  person John Gordon    schedule 02.08.2019


คำตอบ (1)


มีหลายตัวเลือกเพื่อเพิ่มความเร็วในการแทรกข้อมูลจำนวนมาก

1.) commit() หลังจากการวนซ้ำเสร็จสิ้น:

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.) ใช้ตัวช่วยดำเนินการที่รวดเร็วของ psycopg2 เช่น execute_batch() or execute_values()

3.) ความเข้มข้นของสตริงโดยใช้ mogrify():

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

สำหรับการเปรียบเทียบโดยละเอียดของความเร็วในการดำเนินการ INSERT โปรดดูที่เกณฑ์มาตรฐานนี้

person Maurice Meyer    schedule 03.08.2019