PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Chọn truy vấn có giới hạn bù quá chậm

Nó chậm vì nó cần xác định vị trí offset trên cùng và quét 100 hàng tiếp theo. Không có lượng tối ưu hóa nào sẽ thay đổi điều đó khi bạn đang xử lý các khoản chênh lệch lớn.

Điều này là do truy vấn của bạn đúng là hướng dẫn công cụ DB để truy cập nhiều hàng bằng cách sử dụng offset 3900000 - đó là 3,9 triệu hàng. Các tùy chọn để tăng tốc độ này không có nhiều.

RAM siêu nhanh, ổ SSD, v.v. sẽ giúp bạn. Nhưng bạn sẽ chỉ đạt được nhờ một yếu tố không đổi khi làm như vậy, có nghĩa là nó chỉ đơn thuần là đá cái có thể xuống đường cho đến khi bạn đạt được mức bù đắp đủ lớn hơn.

Đảm bảo bảng vừa với bộ nhớ, với nhiều thứ hơn để dự phòng cũng sẽ giúp ích bởi hệ số không đổi lớn hơn - ngoại trừ lần đầu tiên. Nhưng điều này có thể không thực hiện được với một bảng hoặc chỉ mục đủ lớn.

Đảm bảo bạn đang thực hiện quét chỉ mục sẽ hoạt động ở một mức độ nào đó. (Xem câu trả lời của velis; nó có rất nhiều giá trị.) Vấn đề ở đây là, đối với tất cả các mục đích thực tế, bạn có thể coi chỉ mục như một bảng lưu trữ vị trí đĩa và các trường được lập chỉ mục. (Nó được tối ưu hóa hơn mức đó, nhưng đó là ước lượng đầu tiên hợp lý.) Với đủ hàng, bạn vẫn sẽ gặp phải vấn đề với khoảng chênh lệch đủ lớn hơn.

Cố gắng lưu trữ và duy trì vị trí chính xác của các hàng cũng là một cách tiếp cận đắt tiền. (Điều này được gợi ý bởi ví dụ:benjist.) Mặc dù khả thi về mặt kỹ thuật, nhưng nó gặp phải những hạn chế tương tự như những hạn chế bắt nguồn từ việc sử dụng MPTT với cấu trúc cây:bạn sẽ nhận được đáng kể khi đọc nhưng sẽ kết thúc với thời gian ghi quá nhiều khi một nút được chèn, cập nhật hoặc xóa theo cách mà các phần lớn dữ liệu cần được cập nhật cùng với.

Như hy vọng rõ ràng hơn, không có bất kỳ viên đạn ma thuật thực sự nào khi bạn đang đối phó với sự chênh lệch lớn như thế này. Tốt hơn là nên xem xét các phương pháp tiếp cận thay thế.

Nếu bạn đang phân trang dựa trên ID (hoặc trường ngày, hoặc bất kỳ nhóm trường nào có thể lập chỉ mục khác), thì một thủ thuật tiềm năng (chẳng hạn như blogspot sử dụng) sẽ là làm cho truy vấn của bạn bắt đầu tại một điểm tùy ý trong chỉ mục.

Đặt một cách khác, thay vì:

example.com?page_number=[huge]

Làm điều gì đó như:

example.com?page_following=[huge]

Bằng cách đó, bạn giữ được dấu vết về vị trí của mình trong chỉ mục của mình và truy vấn trở nên rất nhanh vì nó có thể đi thẳng đến điểm xuất phát chính xác mà không cần cày qua hàng gazillion:

select * from foo where ID > [huge] order by ID limit 100

Đương nhiên, bạn mất khả năng chuyển đến v.d. trang 3000. Nhưng hãy đưa ra một số suy nghĩ trung thực này:lần cuối cùng bạn chuyển đến một số trang khổng lồ trên một trang web thay vì truy cập thẳng vào kho lưu trữ hàng tháng hoặc sử dụng hộp tìm kiếm của nó là khi nào?

Nếu bạn đang phân trang nhưng muốn giữ trang bù đắp bằng mọi cách, thì một cách tiếp cận khác là cấm sử dụng số trang lớn hơn. Nó không ngớ ngẩn:đó là những gì Google đang làm với kết quả tìm kiếm. Khi chạy một truy vấn tìm kiếm, Google cung cấp cho bạn một số lượng kết quả ước tính (bạn có thể nhận được một con số hợp lý bằng cách sử dụng explain ), và sau đó sẽ cho phép bạn duyệt qua vài nghìn kết quả hàng đầu - không có gì hơn. Trong số những thứ khác, họ làm như vậy vì lý do hiệu suất - chính xác là lý do bạn đang gặp phải.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Người dùng Postgres không tồn tại?

  2. INSERT [...] ON CONFLICT có thể được sử dụng cho các vi phạm khóa ngoại không?

  3. Tùy chọn sao lưu đám mây cho PostgreSQL

  4. GROUP hoặc DISTINCT sau khi JOIN trả về các bản sao

  5. Làm cách nào để khôi phục dữ liệu từ vùng chứa Docker đã bị xóa? Làm thế nào để kết nối lại nó với dữ liệu?