2015-02-05 28 views
8

Tôi đang sử dụng psycopg2 để truy vấn cơ sở dữ liệu Postgresql và cố gắng xử lý tất cả các hàng từ một bảng có khoảng 380M hàng. Chỉ có 3 cột (id1, id2, count) tất cả các số nguyên. Tuy nhiên, khi tôi chạy truy vấn chọn đơn giản bên dưới, quá trình Python bắt đầu tiêu thụ nhiều bộ nhớ hơn và nhiều hơn nữa, cho đến khi nó bị hệ điều hành giết.Psycopg2 sử dụng bộ nhớ trên truy vấn chọn lớn

Minimal dụ làm việc (giả sử mydatabase rằng tồn tại và chứa một bảng gọi là mytable):

import psycopg2 
conn = psycopg2.connect("dbname=mydatabase") 
cur = conn.cursor() 
cur.execute("SELECT * FROM mytable;") 

Tại thời điểm này chương trình bắt đầu nhớ tiêu thụ.

Tôi đã xem xét và quá trình Postgresql hoạt động tốt. Nó đang sử dụng một chút công bằng của CPU, đó là tốt, và một số lượng rất hạn chế của bộ nhớ.

Tôi đã mong psycopg2 trả về một trình lặp mà không cố gắng đệm tất cả các kết quả từ lựa chọn. Sau đó tôi có thể sử dụng cur.fetchone() nhiều lần để xử lý tất cả các hàng.

Vì vậy, làm cách nào để chọn từ bảng hàng 380M mà không sử dụng hết bộ nhớ khả dụng?

Trả lời

12

Bạn có thể sử dụng server side cursors.

cur = conn.cursor('cursor-name') # server side cursor 
cur.itersize = 10000 # how much records to buffer on a client 
cur.execute("SELECT * FROM mytable;") 
+0

Tuyệt vời, cảm ơn vì điều đó! Tôi sẽ thực hiện một vài chỉnh sửa để cải thiện lời giải thích một chút và sau đó chấp nhận. – Carl

+0

Con trỏ này có tồn tại trong máy chủ PostgreSQL hay máy khách Python không? DECLARE cursor_name CURSOR CHO CHỌN * TỪ mytable; –

+0

@FrankHeikens Mọi thứ được thực hiện từ phía máy khách Python trong trường hợp này. Không có con trỏ nào tồn tại phía máy chủ. – Carl

0

Một cách khác để sử dụng con trỏ phía máy chủ:

with psycopg2.connect(database_connection_string) as conn: 
    with conn.cursor(name='name_of_cursor') as cursor: 

     cursor.itersize = 20000 

     query = "SELECT * FROM ..." 
     cursor.execute(query) 

     for row in cursor: 
      # process row 

Psycopg2 sẽ lấy itersize hàng cho khách hàng tại một thời điểm. Sau khi loại bỏ vòng lặp for vòng lặp đó, nó sẽ lấy gói tiếp theo.

Các vấn đề liên quan