Các truy vấn trả về bộ dữ liệu rất lớn trong PostGIS


8

Tôi có một truy vấn PostGIS sẽ trả về hàng triệu hàng:

SELECT 
 t1.id AS id1,
 t2.id AS id2,
 ABS(t1.mean_h - t2.mean_h) AS h_diff, 
 ST_Distance(t1.the_geom, t2.the_geom) AS dist  
FROM tas_ponds as t1, tas_ponds as t2 
WHERE
 (t1.gid > t2.gid) AND
 ST_DWithin(t1.the_geom, t2.the_geom, 17000)

Khi chạy vào psql, tôi gặp out of memory for query resultlỗi.

Googling gợi ý rằng đây là một lỗi trong psql chứ không phải postgres / PostGIS. Việc sửa đổi truy vấn thành biểu mẫu sẽ SELECT ... INTO x FROM ...khắc phục vấn đề? Có cách tiếp cận nào khác được đề xuất để xử lý các bộ dữ liệu rất lớn không?

Câu trả lời:


7

Một số chọc xung quanh xác nhận đây là sự cố máy khách Postgres, không phụ thuộc vào các cân nhắc về không gian hoặc máy chủ: máy khách có bộ nhớ hạn chế để đệm kết quả trước khi hiển thị chúng trên màn hình, vượt quá.

Cách tiếp cận được đề xuất để xử lý việc này là sử dụng cách tiếp cận DECLARE / FETCH để truy cập dữ liệu trong các khối nhỏ hơn tổng số kết quả. Bạn cũng có thể tạo chế độ xem với các thành phần của truy vấn (ví dụ: khoảng cách) để cắt giảm bộ nhớ cần thiết cho chính hoạt động truy vấn.


5

scw đã cho tôi hai phút, vì vậy tôi sẽ không lặp lại câu trả lời của anh ấy. Dưới đây là một số giải pháp khả thi khác:

  • Chỉnh sửa Memoryphần của postgresql.conf. Hãy thử xem bạn có cài đặt bộ nhớ cực thấp có thể ngăn truy vấn chạy không.

  • Cố gắng viết truy vấn vào một tệp và chạy từ dòng lệnh, sử dụng:

    tên tệp psql -f db_name> output_file

  • Nếu bạn định sử dụng kết quả trong một ứng dụng bên ngoài, hãy thử Chạy truy vấn bằng con trỏ từ bên ngoài psql. Ví dụ: tập lệnh Python sẽ chạy truy vấn của bạn:

kịch bản:

try:
    conn = psycopg2.connect("dbname='' user='' host='' password=''") # Fill in
    cur = conn.cursor()
except:
        print 'Unable to connect to the database'
else:
        print 'Connected to database.'

query="""YOUR
         QUERY
         HERE"""
cur.execute(query)

Một con trỏ có thể lặp lại, vì vậy bạn có thể:

for result in cur:
    print result

Hoặc có được tất cả:

 results=cur.fetchall()

2
Tôi có thể sai, nhưng tôi không nghĩ các giải pháp đầu tiên (và có lẽ là thứ hai) sẽ hoạt động. Cái đầu tiên sửa đổi bộ nhớ máy chủ và đây là vấn đề của máy khách, không liên quan đến bộ nhớ khả dụng trong DMBS và cái thứ hai có thể sẽ gặp vấn đề tương tự trừ khi chỉ đệm nó vào màn hình là vấn đề. Giải pháp thứ ba của bạn tốt hơn IMO của tôi, vì nó cho phép kiểm soát chi tiết trong một môi trường linh hoạt với con trỏ, đây là một mẹo nhỏ hơn trong SQL thô. +1
scw

@scw có lẽ bạn đúng về giải pháp đầu tiên (và có lẽ thứ hai). Vấn đề là, đôi khi những thủ thuật cụ thể này dường như hoạt động với PostgreSQL, chúng có thể cải thiện hiệu suất chung và chúng mất ít thời gian và công sức để thử. Đã học được rất nhiều từ câu trả lời của bạn.
Adam Matan

2

Đối với bản ghi, trong trường hợp của tôi, lưu trữ tập dữ liệu được trả về trong một bảng khác bằng cách sử dụng SELECT ... INTO ...cú pháp.

Nó không chỉ giải quyết vấn đề hết bộ nhớ, mà còn nhanh hơn đáng kể so với truy vấn ban đầu.


1

Lập chỉ mục là rất quan trọng trong Postgres và PostGIS

http://postgis.refraction.net/docs/ch04.html#id2794434

Đề xuất các chỉ mục GiST (Cây tìm kiếm tổng quát) cho các bộ dữ liệu rất lớn .... (cũng là "null an toàn") ví dụ CREATE INDEX [tên chỉ mục] BẬT [tablename] SỬ DỤNG GIST ([hình học]];

Sau khi xây dựng một chỉ mục, điều quan trọng là buộc PostgreSQL thu thập số liệu thống kê bảng, được sử dụng để tối ưu hóa các kế hoạch truy vấn

PHÂN TÍCH VACUUM [tên_bảng] [cột_name]; CHỌN UPDATE_GEOMETRY_STATS ([tên_bảng], [cột_name]);

cũng là một tài liệu tham khảo tốt là: Tận dụng lợi thế của chỉ mục http://postgis.refraction.net/docs/ch04.html#id2794685


Đúng, tôi đã lập chỉ mục và hút bụi các bảng và xác nhận các chỉ mục của tôi đang được sử dụng thông qua EXPLAIN, v.v. Tuy nhiên, vấn đề của tôi không phải là tốc độ (tại thời điểm này), do lỗi bộ nhớ.
đánh dấu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.