2013-08-04 42 views
10

Giả sử truy vấn sau đây:Khi nào một truy vấn SELECT bắt đầu trả về các hàng?

SELECT * FROM table; 

DBMS Sẽ cung cấp cho tôi những dòng đầu tiên ngay sau khi nó lấy nó hoặc sẽ nó lần đầu tiên lấy tất cả các hàng (lưu chúng trong một số loại đệm) và sau đó cung cấp cho tôi tất cả các hàng cùng một lúc?

Nếu câu hỏi của tôi không rõ ràng. Giả sử rằng số lượng hàng trong table là như vậy mà DBMS sẽ mất chính xác 60 phút để lấy tất cả các hàng. DBMS sẽ trả về các hàng dần dần thông qua 60 phút, hoặc tôi sẽ phải chờ 60 phút trước khi nhận được bất kỳ dữ liệu nào không?

+3

Hmmm ... thú vị. Thử nghiệm của bạn đã đề xuất điều gì? –

+0

@AndrewMorton Thử nghiệm của tôi cho thấy rằng nó sử dụng một số loại bộ nhớ cache. Ngoài ra, tôi tin rằng nó sẽ dễ dàng hơn để xử lý các giao dịch với phương pháp tiếp cận bộ nhớ cache. Tuy nhiên, tôi đã thử nghiệm chỉ với 'psql' cho đến nay, vì vậy tôi không biết nếu hành vi là do' psql' hoặc do dbms. –

+2

psql có hành vi giống như ứng dụng đơn giản điển hình. Nó dựa trên libpq, vì vậy libpq thu thập tất cả dữ liệu trong bộ nhớ ở phía máy khách và khi truy vấn hoàn tất, sau đó trả về điều khiển cho máy khách. Bạn có thể xác định lại nó để sử dụng con trỏ bằng cách đặt FETCH_COUNT thành 1000 (trả về cho khách sau khi tìm nạp 1000 hàng) - \ set FETCH_COUNT 1000 –

Trả lời

8

Trong PostgreSQL, máy chủ sẽ thực sự trả về các hàng cho máy khách ngay khi chúng có sẵn nếu gói thực thi truy vấn cho phép nó. Đây là trường hợp trong ví dụ đơn giản của bạn. Trong trường hợp khác, nếu bạn có thể có một loại ở cuối, ví dụ, và sẽ phải chờ đợi để kết thúc.

Nhưng nếu bạn sử dụng giao diện libpq chuẩn, thư viện khách sẽ xây dựng toàn bộ kết quả trong bộ nhớ trước khi trả về kết quả cho chương trình khách. Để có được kết quả theo hàng, bạn cần sử dụng single-row mode trong libpq. Nếu bạn sử dụng các giao diện khác hoặc các ngôn ngữ khác, kết quả có thể khác nhau.

+0

Bạn có biết giải pháp nào trước 9.2 không? –

+0

Sử dụng con trỏ phía máy chủ. –

0

Điều đó tùy thuộc. Ví dụ, Cơ sở dữ liệu Oracle sẽ tối ưu hóa cho thông lượng theo mặc định và cố gắng trả về tất cả các hàng, hoặc bạn có thể hướng dẫn trình tối ưu hóa trả lại hàng n đầu tiên với `/ * + FIRST_ROWS (n) */optimizer hint.

Đối với PostgresSQL, nó không có gợi ý về bộ chọn lọc (xem thesetwo liên kết). Tôi có thể giả định nó sẽ cố gắng tối ưu hóa cho thông lượng theo mặc định.

+4

PostgreSQL không sử dụng gợi ý cho mục đích này, nhưng khi bạn sử dụng con trỏ, truy vấn được tối ưu hóa cho các hàng 10% nhanh đầu tiên (giá trị mặc định của cursor_tuple_fraction). –

3

Không có quy tắc cứng ở đây. Nhưng trên thực tế, công cụ cơ sở dữ liệu nên thích trả lại hàng ngay khi chúng có sẵn. Lợi thế hiệu quả là lớn và rõ ràng.

Lưu ý rằng điều này là không thể cho tất cả các truy vấn. Một ví dụ rất phổ biến là mệnh đề order by không có chỉ mục hỗ trợ. Để sắp xếp, cơ sở dữ liệu phải tạo một bản sao phía máy chủ của bảng được sắp xếp. Điều này có nghĩa là nó không thể bắt đầu trả lại hàng cho đến khi hoàn tất thao tác sắp xếp.

1

Hầu hết, nếu không phải tất cả, máy chủ dựa trên SQL sẽ không cho phép bạn xem bất kỳ hàng nào cho đến khi truy vấn hoàn tất tìm kiếm. Một số máy chủ cung cấp chỉ thị FIRST ROWS (gợi ý) cho máy chủ để cung cấp tập hợp các hàng đầu tiên sớm hơn. Xem liên quan của tôi SO question and answers để biết thêm thông tin về chủ đề này.

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