Tôi đang phát triển một chương trình bằng Python truy cập cơ sở dữ liệu MySQL bằng MySQLdb. Trong một số trường hợp, tôi phải chạy lệnh INSERT hoặc REPLACE trên nhiều hàng. Tôi hiện đang làm như sau:Tại sao thực thi chậm trong 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])
Nó hoạt động tốt, nhưng nó là loại khó xử. Tôi đã tự hỏi nếu tôi có thể làm cho nó dễ dàng hơn để đọc, và tôi phát hiện ra về lệnh executemany. Tôi đã thay đổi mã của mình để trông giống như sau:
db.executemany("REPLACE INTO " + table + " (" + ",".join(cols) + ") " +
"VALUES(" + ",".join(["%s"] * len(cols)) + ")",
[tuple(row[col] for col in cols) for row in data])
Nó vẫn hoạt động nhưng chạy chậm hơn rất nhiều. Trong các thử nghiệm của tôi, đối với các tập dữ liệu tương đối nhỏ (khoảng 100-200 hàng), nó chạy chậm hơn khoảng 6 lần. Đối với các tập dữ liệu lớn (khoảng 13.000 hàng, lớn nhất tôi mong đợi để xử lý), nó chạy chậm hơn khoảng 50 lần. Tại sao nó làm điều này?
Tôi thực sự muốn đơn giản hóa mã của mình, nhưng tôi không muốn giảm hiệu suất lớn. Có ai biết về bất kỳ cách nào để làm cho nó nhanh hơn?
Tôi đang sử dụng Python 2.7 và MySQLdb 1.2.3. Tôi đã cố gắng tinkering với hàm setinputsizes, nhưng điều đó dường như không làm gì cả. Tôi đã xem mã nguồn MySQLdb và có vẻ như nó không nên làm gì cả.
bạn chèn/thay thế bao nhiêu hàng? câu lệnh thứ hai của bạn tạo ra một danh sách lớn trong bộ nhớ trước khi cho nó vào mysql. – nosklo
Tôi đang thay thế tối đa 13.000 hàng. Tôi không nghĩ rằng việc tạo danh sách là nút cổ chai. Nếu tôi tạo danh sách nhưng không chuyển nó vào con trỏ db, nó hầu như không mất chút thời gian nào cả. –
(Sẽ không trả lời câu hỏi, nhưng ...) 'CHERTN ... VỀ CẬP NHẬT KHÓA CHÍNH ...' gần như luôn luôn tốt hơn 'REPLACE ...'. –