2014-12-11 13 views
6

Sử dụng postgresql 9.4 chúng ta có một bảng liên lạc đơn giản với (id văn bản không null (như pk), blob json) để thử nghiệm với porting một cơ sở dữ liệu CRMDB CRM. Cuối cùng, chúng ta sẽ chia ra thành nhiều cột hơn, và xử lý dữ liệu một cách tự nhiên hơn cho một rdbms, nhưng đó là ngoài thời điểm hiện tại.Postgresql Offset Behavior với cột json

Có khoảng 100 nghìn hàng.

Tôi biết rằng các chuyên gia thực hiện postgresql Hardcore khuyên chống lại bằng cách sử dụng bù đắp tuy nhiên tôi có thể chấp nhận một hình phạt hiệu suất nhỏ (hài lòng với bất cứ điều gì dưới 100mili-giây)

SELECT id FROM couchcontacts OFFSET 10000 LIMIT 10 

Đúng như dự đoán mất < 10ms

SELECT blob->>'firstName' FROM couchcontacts LIMIT 10 

Cũng cần < 10ms (giả sử 10 mã giải mã json trên cột blob tại đây)

SELECT blob->>'firstName' FROM couchcontacts OFFSET 10000 LIMIT 10 

Tăng tối đa 10 giây !! Lưu ý không hiệu quả bù đắp sang một bên lý do tại sao điều này có lẽ gây ra 10,010 json decode ops? Khi chiếu không có tác dụng phụ, tôi không hiểu lý do điều này không thể nhanh chóng?

Đây có phải là hạn chế của chức năng json tương đối mới đối với bưu điện không? và do đó không thể xác định được ->> opereator có tạo ra tác dụng phụ không?

Thú vị viết lại truy vấn để này mang nó trở lại dưới 10milliseconds

SELECT jsonblob->>'firstName' FROM couchdbcontacts WHERE id IN (SELECT id FROM couchcontacts OFFSET 10000 LIMIT 10) 

Có cách nào để đảm bảo bù đắp json doesnt giải mã các hồ sơ offsetted? (ví dụ: không thực hiện phép chiếu đã chọn)

"Limit (cost=1680.31..1681.99 rows=10 width=32) (actual time=12634.674..12634.842 rows=10 loops=1)" 
" -> Seq Scan on couchcontacts (cost=0.00..17186.53 rows=102282 width=32) (actual time=0.088..12629.401 rows=10010 loops=1)" 
"Planning time: 0.194 ms" 
"Execution time: 12634.895 ms" 
+0

Điều đó trông giống như một góc thô của tính năng mới này. Hãy báo cáo nó như là một lỗi cho Postgresql. Tôi đoán cách giải quyết là phân trang thủ công, giống như bạn đã thể hiện bản thân. – Thilo

+1

'GIẢI PHÁP GIẢI THÍCH 'vui lòng? Tôi không hoàn toàn bị thuyết phục bởi lời giải thích về sự khác biệt. Bạn có hồ sơ/'perf top'/etc để xem nếu lời giải thích giả thuyết của bạn phù hợp với hành vi quan sát? Mặc dù trên suy nghĩ thứ hai ... Tôi nghĩ rằng nếu bạn yêu cầu một tập kết quả với một bù đắp, PostgreSQL nên đánh giá các biểu thức trong các hàng bị loại bỏ trừ khi nó có thể chứng minh chúng không có tác dụng phụ. Vì vậy, có lẽ nó đang đánh giá các biểu thức json ... và cho là nó nên được trừ khi nó có thể chứng minh họ không thể hủy bỏ các truy vấn với một 'ERROR' hoặc thay đổi trạng thái cơ sở dữ liệu. –

+0

Given - >> được xây dựng trong nhà điều hành, không nên postgresql biết điều này isnt gây ra tác dụng phụ? Có cách nào để gợi ý nó không có tác dụng phụ gây ra ?. Cập nhật với giải thích phân tích –

Trả lời

5

Tôi đã chạy một vài thử nghiệm và tôi thấy các hành vi tương tự. Mỗi trong số này có những khác biệt không đáng kể trong hoạt động:

  • select id ...
  • select indexed_field ...
  • select unindexed_field ...
  • select json_field ...
  • select * ...

Điều này, tuy nhiên, hiển thị sự khác biệt về hiệu suất:

  • select json_field->>'key' ...

Khi json_field là null, tác động hiệu suất là không đáng kể. Khi nó trống rỗng, nó làm giảm đi rất nhiều thứ. Khi nó được lấp đầy, nó giảm đáng kể. Và khi trường được tải với dữ liệu lớn hơn, nó sẽ làm giảm chất lượng vật chất.

Nói cách khác, Postgres dường như muốn unserialize dữ liệu json cho mỗi hàng nó truy cập. (Đó có thể là một lỗi, và một trong số đó ảnh hưởng lớn đến các nhà phát triển RoR khi thấy họ sử dụng json như thế nào.)

Fwiw, tôi lưu ý rằng sắp xếp lại các truy vấn để nó sử dụng một CTE sẽ làm việc xung quanh vấn đề này:

with data as (
    select * from table offset 10000 limit 10 
) 
select json_field->>'key' from data; 

(Nó có thể có được một kế hoạch chỉ-rất-tốt hơn một chút so với các truy vấn id IN (...) rằng bạn đã đánh dấu.)

+0

Cảm ơn các bài kiểm tra. Chỉ cần thêm chúng tôi không sử dụng RoR, nhưng Clojure, như nhiều nhà phát triển đang đẩy Postgres như một thay thế NoSQL (blog, hội nghị, microbenchmarks) Im chắc chắn các kịch bản này sẽ trở nên phổ biến hơn trên vô số các ngăn xếp. –

+1

Vâng. Chỉ trong trường hợp, vui lòng dành một phút để báo cáo vấn đề về hiệu suất pg hoặc danh sách pg-bugs. Tôi đoán đây là sự giám sát trong cơ sở mã: các hàm json khác nhau liên quan đến việc đọc là không thay đổi khi tôi có thể nói, vì vậy tôi không thấy bất kỳ lý do gì để làm phiền khi đánh giá chúng khi loại bỏ các hàng. –

+0

Tôi đã báo cáo pg-bugs và sẽ đợi để xem điều gì xảy ra (danh sách được kiểm duyệt), tôi sẽ để lại câu trả lời này chưa được trả lời trong một hoặc hai ngày vì lý do kỳ lạ đó là do thiết kế. –