2009-11-27 19 views
27

Tôi phải đối phó với một tập hợp kết quả lớn (có thể là hàng trăm nghìn hàng, đôi khi nhiều hơn).
Rất tiếc, chúng cần được truy xuất tất cả cùng một lúc (khi khởi động).Làm thế nào để sử dụng hiệu quả SSHCursor của MySQLDB?

Tôi đang cố gắng làm điều đó bằng cách sử dụng càng ít bộ nhớ càng tốt.
Bằng cách xem trên SO, tôi thấy rằng việc sử dụng SSCursor có thể là những gì tôi đang tìm kiếm, nhưng tôi vẫn không thực sự biết cách sử dụng chính xác chúng.

Đang thực hiện một số fetchall() từ con trỏ cơ sở hoặc SScursor giống nhau (trong điều khoản sử dụng bộ nhớ)?
Tôi có thể 'phát trực tuyến' từ con trỏ của tôi từng hàng một (hoặc một số ít) và nếu có,
cách tốt nhất để làm như vậy là gì?

Trả lời

28

Tôi đồng ý với câu trả lời Otto Allmendinger, nhưng để làm cho bình luận rõ ràng Denis Otkidach của, đây là cách bạn có thể lặp qua các kết quả mà không cần dùng lấy() chức năng của Otto:

import MySQLdb.cursors 
connection=MySQLdb.connect(
    host="thehost",user="theuser", 
    passwd="thepassword",db="thedb", 
    cursorclass = MySQLdb.cursors.SSCursor) 
cursor=connection.cursor() 
cursor.execute(query) 
for row in cursor: 
    print(row) 
+0

Tôi đoán đó là những gì tôi đang tìm kiếm, cảm ơn – Sylvain

+0

Việc này có tìm nạp từng hàng một không? Nếu không có bao nhiêu hàng này lấy trong một đi. Tôi có một db với hơn 37 triệu hồ sơ. Tôi cần phải đọc các bản ghi từng người một và đặt chúng trong một tập tin (với một số điều bổ sung như vậy không thể là một bãi chứa đơn giản). Điều này có thể được thực hiện song song bằng cách nào đó. Ví dụ tôi lấy 10000 hàng ghi chúng và trong khi tôi viết chúng một số hàng đang được lấy và như vậy .. – Sohaib

+0

@Sohaib: Điều này tìm nạp một hàng tại một thời điểm. Nếu vấn đề của bạn là CPU bị ràng buộc, thì bạn có thể sử dụng đa xử lý (Python2/3) hoặc concurrent.futures (trong Python3) để thiết lập nhiều trình đọc DB, nhưng bạn chỉ nên sử dụng một trình ghi vào tệp, hoặc các bản ghi khác sẽ nhận được bị cắt xén. [Nếu vấn đề của bạn là IO bị ràng buộc] (http://eli.thegreenplace.net/2012/01/16/python-parallelizing-cpu-bound-tasks-with-multiprocessing/) - nếu ghi vào tập tin là nút cổ chai - sau đó thiết lập nhiều người đọc sẽ không tăng tốc độ công việc. – unutbu

9

Chắc chắn sử dụng SSCursor khi tìm nạp tập hợp kết quả lớn. Nó tạo ra một sự khác biệt rất lớn đối với tôi khi tôi gặp vấn đề tương tự. Bạn có thể sử dụng nó như thế này:

import MySQLdb 
import MySQLdb.cursors 

connection = MySQLdb.connect(
     host=host, port=port, user=username, passwd=password, db=database, 
     cursorclass=MySQLdb.cursors.SSCursor) # put the cursorclass here 
cursor = connection.cursor() 

Bây giờ bạn có thể thực hiện truy vấn của mình với cursor.execute() và sử dụng con trỏ làm trình lặp.

Chỉnh sửa: loại bỏ trình tự phát triển không cần thiết trong nhà, nhờ Denis!

+3

Đối tượng con trỏ có thể lặp lại, vì vậy không cần viết trình tạo trên đó. Nếu không, bạn có thể sử dụng 'iter (cursor.fetchone, None)'. –

0

Ngoài ra, bạn có thể sử dụng SSCursor bên ngoài đối tượng kết nối (nó là khá quan trọng khi bạn đã xác định kết nối và không muốn tất cả các kết nối sử dụng SSCursor làm lớp con trỏ).

import MySQLdb 
from MySQLdb.cursors import SSCursor # or you can use SSDictCursor 

connection = MySQLdb.connect(
     host=host, port=port, user=username, passwd=password, db=database) 
cursor = SSCursor(connection) 
cursor.execute(query) 
for row in cursor: 
    print(row) 
Các vấn đề liên quan