Cơ sở dữ liệu Triển khai ĐẶT HÀNG THEO trong một truy vấn con


10

Tôi đang sử dụng một ứng dụng (MapServer - http://mapserver.org/ ) bao bọc các câu lệnh SQL, để câu lệnh ORDER BY nằm trong truy vấn bên trong. Ví dụ

SELECT * FROM (
        SELECT ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

Ứng dụng này có nhiều trình điều khiển cơ sở dữ liệu khác nhau. Tôi chủ yếu sử dụng trình điều khiển MS SQL Server và SQL Server 2008. Điều này sẽ gây ra lỗi nếu tìm thấy ORDER BY trong truy vấn con.

Từ MS Docs (mặc dù điều này là dành cho SQL Server 2000 nhưng dường như nó vẫn được áp dụng):

Khi bạn sử dụng mệnh đề ORDER BY trong chế độ xem, hàm nội tuyến, bảng dẫn xuất hoặc truy vấn con, nó không đảm bảo đầu ra theo thứ tự. Thay vào đó, mệnh đề ORDER BY chỉ được sử dụng để đảm bảo rằng tập kết quả được tạo bởi toán tử Top có cấu trúc nhất quán. Mệnh đề ORDER BY chỉ đảm bảo một tập kết quả được đặt hàng khi nó được chỉ định trong câu lệnh SELECT ngoài cùng.

Tuy nhiên, cùng loại truy vấn khi chạy trong Postgres (9) và kết quả trả về của Oracle - với thứ tự như được xác định trong truy vấn con. Trong Postgres, kế hoạch truy vấn hiển thị kết quả được sắp xếp và ghi chú phát hành Postgres bao gồm mục ngụ ý các đơn đặt hàng truy vấn phụ được sử dụng:

Tránh sắp xếp khi truy vấn phụ ORDER BY khớp với truy vấn trên

http://en.wikipedia.org/wiki/Order_by tuyên bố:

Mặc dù một số hệ thống cơ sở dữ liệu cho phép đặc tả mệnh đề ORDER BY trong các mục con hoặc xem định nghĩa, sự hiện diện ở đó không có hiệu lực.

Tuy nhiên, từ việc kiểm tra kế hoạch truy vấn của riêng tôi:

  • SQL Server 2008 không hỗ trợ ORDER BY trong truy vấn con
  • Postgres 9 không hỗ trợ ĐẶT HÀNG B inNG trong truy vấn con
  • Oracle 10g hỗ trợ ĐẶT HÀNG B inNG trong một truy vấn con

Vì vậy, câu hỏi của tôi là có bất kỳ liên kết nào có thể chính thức xác nhận hoặc từ chối rằng Postgres và Oracle không cho phép sắp xếp trong một truy vấn con?


2
Chỉ vì bạn quan sát một số kết quả nhất định không làm cho chúng được đảm bảo. Nếu bạn muốn sự nhất quán, hãy đặt hàng ở bên ngoài. Giai đoạn = Stage.
Aaron Bertrand

Lý tưởng nhất là những gì sẽ được thực hiện. Tuy nhiên, để đi đến giai đoạn này sẽ liên quan đến những thay đổi đối với logic cốt lõi và nhiều trình điều khiển cơ sở dữ liệu. Vì vấn đề này đã không được báo cáo trong nhiều năm, có vẻ như một số dbs thường xuyên thực hiện ĐẶT HÀNG B inNG trong các truy vấn con. Sẽ thật tốt nếu biết cái nào nếu có thể.
geographika

2
@geographika Ngay cả khi một số DBMS làm như vậy một cách nhất quán cho đến bây giờ, không có gì đảm bảo họ sẽ tiếp tục làm điều tương tự trong tương lai. Ví dụ, các cải tiến của trình tối ưu hóa của MySQL trong 5.6 (và MariaDB 5.3) sẽ xác định ORDER BYtruy vấn con là dự phòng và không thực hiện sắp xếp không cần thiết.
ypercubeᵀᴹ

Câu trả lời:


14

Bạn sẽ phải làm cho ứng dụng của mình không đặt ORDER BYbên trong truy vấn con (có thể nó có tùy chọn không sử dụng truy vấn con không cần thiết ở vị trí đầu tiên). Như bạn đã phát hiện ra, cú pháp này không được hỗ trợ trong SQL Server mà không có TOP. Và với TOP, trừ khi bạn muốn để lại một số hàng, sử dụng TOP 100 PERCENTsẽ hiển thị ORDER BYtối ưu hóa đi.

Và trong Oracle và PostGres, chỉ vì cú pháp được hỗ trợ , không có nghĩa là nó được tuân theo. Và chỉ vì bạn quan sát nó như được tuân theo trong một số tình huống, không có nghĩa là nó sẽ tiếp tục được tuân theo khi các phiên bản mới xuất hiện hoặc có những thay đổi tinh tế đối với dữ liệu, số liệu thống kê, chính truy vấn hoặc môi trường của bạn.

Tôi có thể đảm bảo với bạn rằng, không nghi ngờ gì nữa , nếu bạn muốn đảm bảo về trật tự, bạn cần đặt ORDER BYtruy vấn ngoài cùng. Đây phải là một học thuyết bạn nắm giữ bất kể bạn đang sử dụng nền tảng nào.

Bạn đang yêu cầu một liên kết chính thức nói rằng một cái gì đó không được hỗ trợ. Điều này giống như tìm trong hướng dẫn sử dụng xe của bạn cho một tuyên bố chính thức rằng xe của bạn không thể bay.


Cảm ơn. Tôi nghĩ MSSQL có cách tiếp cận đúng khi đưa ra lỗi. Cả hỗ trợ và triển khai sắp xếp trên các truy vấn bên trong, khi nó đi ngược lại nguyên tắc SQL cốt lõi, dường như là một công thức cho thảm họa. Không chắc chắn về sự tương tự xe hơi mặc dù - bạn cần thêm tìm kiếm nó trong hướng dẫn trong khi chiếc xe thực sự đang bay ..
geographika

-1

Tôi thừa nhận điều này là nhếch nhác nhưng nếu bạn đang ở trong tình trạng khó khăn, hãy thử trả lại số hàng hàng đầu trong truy vấn con. Trả lại 100 phần trăm hàng đầu không hoạt động nhưng nếu bạn muốn vượt qua rắc rối, bạn có thể truy vấn số lượng hàng và chuyển số đó lên TOP dưới dạng một biến. Tôi đã thử nghiệm điều này trên cơ sở dữ liệu được đặt ở mức tương thích 80, vì vậy tôi nghĩ rằng nó nên hoạt động với SQL 2000.

SELECT * FROM (
        SELECT TOP (100000) ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

Tôi đã thử điều này ban đầu và nó dường như sắp xếp tốt cho các bộ dữ liệu nhỏ. Tuy nhiên, khi tôi nhận được các bản ghi rất lớn, việc sắp xếp lại trở thành ngẫu nhiên trong SQL Server 2008R2. Có lẽ liên quan đến kích thước bộ nhớ / trang?
geographika

Xin lỗi nó không giúp được gì. Việc chọn 100 phần trăm hàng đầu cũng khiến việc sắp xếp trở lại ngẫu nhiên.
DBNull

Điều này sẽ không hoạt động nếu truy vấn đi song song, đặc biệt nếu Namekhông phải là duy nhất. Nó có thể không tiếp tục hoạt động bình thường nếu trình tối ưu hóa chọn một chỉ mục khác nhau, với thứ tự cột khóa khác nhau.
Erik Darling
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.