Tại sao ĐẶT HÀNG B BYNG không thuộc về Chế độ xem?


51

Tôi hiểu rằng bạn không thể có ORDER BY trong một cái nhìn. (Ít nhất là trong SQL Server 2012 tôi đang làm việc với)

Tôi cũng hiểu rằng cách "chính xác" để sắp xếp một khung nhìn là bằng cách đặt ORDER BYxung quanh SELECTcâu lệnh truy vấn khung nhìn.

Nhưng tương đối mới đối với SQL thực tế và cách sử dụng các khung nhìn, tôi muốn hiểu tại sao điều này được thực hiện như vậy bởi thiết kế. Nếu tôi đã theo dõi lịch sử một cách chính xác, điều này đã từng có thể và đã bị xóa rõ ràng khỏi SQL Server 2008, v.v. (đừng trích dẫn tôi về phiên bản chính xác).

Tuy nhiên, lý do tốt nhất tôi có thể đưa ra là lý do tại sao Microsoft loại bỏ tính năng này là vì "chế độ xem là một bộ sưu tập dữ liệu chưa được sắp xếp".

Tôi giả định rằng có một lý do hợp lý, hợp lý là tại sao một Chế độ xem không được sắp xếp. Tại sao một khung nhìn không thể là một bộ sưu tập dữ liệu được làm phẳng? Tại sao cụ thể không phân loại? Dường như không khó để đưa ra các tình huống trong đó (ít nhất là với tôi / IMHO) có vẻ như hoàn toàn trực quan để có một chế độ xem được sắp xếp.


2
Câu trả lời đầu tiên là tại chỗ hoàn hảo. Tôi sẽ đề nghị nếu bạn muốn đặt một quan điểm tại sao bạn không làm điều này. Chọn [Cột] Từ [YourView] Sắp xếp theo [Cột]
Zane

Câu trả lời ngắn gọn: "Vì cùng một lý do mà ORDER BY không thuộc về một bảng."
ypercubeᵀᴹ

Câu trả lời:


38

(Tất nhiên, các quan điểm được lập chỉ mục sang một bên.)

Một khung nhìn không được cụ thể hóa - dữ liệu không được lưu trữ, vậy làm thế nào để sắp xếp nó? Một khung nhìn giống như một thủ tục được lưu trữ chỉ chứa một SELECTkhông có tham số ... nó không chứa dữ liệu, nó chỉ giữ định nghĩa của truy vấn. Do các tham chiếu khác nhau cho chế độ xem có thể cần dữ liệu được sắp xếp theo các cách khác nhau, nên cách bạn thực hiện việc này - giống như chọn từ bảng, cũng là một tập hợp các hàng chưa được sắp xếp, theo định nghĩa - là bao gồm thứ tự theo truy vấn bên ngoài .

Ngoài ra để cung cấp một cái nhìn sâu sắc về lịch sử. Bạn không bao giờ có thể đưa ORDER BYvào một cái nhìn, mà không bao gồm TOP. Và trong trường hợp này, ORDER BYlệnh được đưa vào bởi những hàng nào TOP, không phải cách chúng được trình bày. Nó đã xảy ra như vậy trong SQL Server 2000, nếu TOP100 PERCENThoặc {some number >= number of rows in the table}, trình tối ưu hóa khá đơn giản và cuối cùng nó đã tạo ra một kế hoạch với một loại phù hợp với TOP/ORDER BY. Nhưng hành vi này không bao giờ được đảm bảo hoặc ghi lại - nó chỉ dựa vào quan sát, đó là một thói quen xấu . Khi SQL Server 2005 xuất hiện, hành vi này bắt đầu "phá vỡ" vì những thay đổi trong trình tối ưu hóa dẫn đến các kế hoạch và toán tử khác nhau được sử dụng - trong số những thứ khác,TOP / ORDER BYsẽ bị bỏ qua hoàn toàn nếu nó là TOP 100 PERCENT. Một số khách hàng phàn nàn về điều này lớn đến mức Microsoft đã ban hành một cờ theo dõi để khôi phục hành vi cũ. Tôi sẽ không nói cho bạn biết cờ là gì vì tôi không muốn bạn sử dụng nó và tôi muốn chắc chắn rằng ý định đó là chính xác - nếu bạn muốn một thứ tự sắp xếp có thể dự đoán được, hãy sử dụng ORDER BYtruy vấn bên ngoài.

Để tóm tắt và cũng giống như làm rõ một điểm bạn đã thực hiện: Microsoft đã không xóa bất cứ điều gì. Họ đã làm cho sản phẩm tốt hơn và như một tác dụng phụ, hành vi không được bảo đảm, không có giấy tờ này trở nên kém tin cậy hơn. Nhìn chung, tôi nghĩ rằng sản phẩm là tốt hơn cho nó.


Dưới đây đã đề cập (trong một bình luận) rằng TOPthực hiện thao tác con trỏ trên tập kết quả. Do đó, nó có thể có một trật tự rõ ràng.
Tim Schmelter

@TimSchmelter không giúp ích gì khi trình tối ưu hóa nhìn thấy TOP 100 PERCENT / ORDER BYvà loại bỏ nó hoàn toàn khỏi kế hoạch. Hãy thử nó.
Aaron Bertrand

Đó chỉ là một sidenote. Phần còn lại của nhận xét là như sau: "thủ thuật CHỌN x được lên kế hoạch để không bị phản đối trong phiên bản tương lai của SQL Server, vì vậy tốt nhất là không nên sử dụng nó."
Tim Schmelter

@TimSchmelter nó đã không còn hoạt động. Tôi không nghĩ rằng nó sẽ ngừng hoạt động trong bất kỳ phiên bản mới nào sớm, bởi vì nó sẽ phá vỡ quá nhiều mã hiện có.
Aaron Bertrand

2
@TimSchmelter có thứ tự không nói về thứ tự của các hàng, nó đang nói về thứ tự của các cột trong một hàng. Trong SQL Server, chúng tôi thường không nói về một hàng là một tuple vì việc triển khai vật lý của một hàng quá rõ ràng đối với chúng tôi (bảng liệt kê các cột theo thứ tự bạn đã xác định chúng).
Aaron Bertrand

9

Nếu một khung nhìn được phép sắp xếp thì thứ tự của kết quả ở đây là gì?

CREATE VIEW dbo.V1
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number ASC

GO

CREATE VIEW dbo.V2
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number DESC

GO

SELECT *
FROM   dbo.V1
       JOIN dbo.V2
         ON V1.number = V2.number 

Tôi không nhận được điểm này. Thay vì viết chế độ xem cơ sở dữ liệu, bạn có thể viết truy vấn sql bình thường. Vì vậy, thứ tự của kết quả trong trường hợp đó là gì? cảm ơn
hqt

7

một khả năng là để tránh các loại xung đột - nếu chế độ xem được sắp xếp theo một thứ tự và lựa chọn trên chế độ xem đó được sắp xếp theo một thứ tự khác (không nhận thức được loại sắp xếp), có thể có hiệu suất nhấn. Vì vậy, sẽ an toàn hơn khi để lại yêu cầu sắp xếp cho người dùng.

một lý do khác, sắp xếp đi kèm với chi phí hiệu năng, vậy tại sao lại phạt tất cả người dùng chế độ xem, khi chỉ một số người dùng cần loại này ..


5

ANSI SQL chỉ cho phép ORDER BYtruy vấn trên cùng vì nhiều lý do, một là những gì xảy ra khi một subselect / view / CTE được nối với một bảng khác và truy vấn bên ngoài có ORDER BYchính nó.

Máy chủ SQL không bao giờ hỗ trợ nó trong chế độ xem (trừ khi bạn lừa nó bằng cách sử dụng cái TOP 100 PERCENTmà theo tôi chủ yếu là gây ra lỗi).

Ngay cả khi bạn kích hoạt lỗi, kết quả vẫn chưa bao giờ đáng tin cậy và việc sắp xếp không phải lúc nào cũng diễn ra theo cách bạn mong đợi.

Xem bài đăng trên blog này của nhóm Trình tối ưu hóa truy vấn để được giải thích kỹ thuật đầy đủ TOP 100 Phần trăm ĐẶT HÀNG B BYNG Được coi là có hại.

Việc thực hiện kế hoạch mặc định cho mã này xảy ra để sắp xếp các hàng như một phần của việc thực hiện thao tác TOP. Thông thường, điều này có nghĩa là các kết quả đã được trả về theo thứ tự được sắp xếp và điều này khiến khách hàng tin rằng có một sự đảm bảo rằng các hàng đã được sắp xếp. Đây thực sự không phải là trường hợp. Nếu bạn muốn các hàng được trả về cho người dùng theo thứ tự được sắp xếp, bạn cần sử dụng ORDER BY trên khối truy vấn ngoài cùng (theo ANSI) để đảm bảo thứ tự trình bày đầu ra.


3

Các khung nhìn hoạt động giống như các bảng có nội dung được xác định bởi các kết quả của truy vấn.

Bàn không có thứ tự; chúng chỉ là những hàng ghế.

Do đó, lượt xem cũng không có thứ tự. Tuy nhiên, bạn có thể sắp xếp chúng bằng cách chọn các hàng trong một ĐẶT HÀNG cụ thể.


1
Bảng ... chỉ là túi hàng - và sau đó viwes chỉ là túi ảo của hàng ảo - chế độ xem "không tồn tại" - ví dụ: không có dữ liệu nào được lưu trữ cho chúng - chúng chỉ là "định nghĩa được lưu trữ của truy vấn đối với được thực thi ", về cơ bản.
marc_s

1
+1 Sự tương đương của các tabel và lượt xem dường như là lý do chính tại sao các lượt xem không nên chứa "thứ tự bởi"
miracle173

1
"Lượt xem hoạt động như bảng" . Tôi sẽ nói rằng "Lượt xem hoạt động giống như bảng cơ sở. Lượt xem là bảng."
ypercubeᵀᴹ

-2

Một câu trả lời chưa được đưa ra là "thứ tự bởi" có thể can thiệp vào việc đẩy vị ngữ có thể ảnh hưởng lớn đến hiệu suất.

Một ví dụ có chế độ xem cuộn một tập hợp dữ liệu lớn thành một bản tóm tắt 10 dòng nằm trong top 10 / Sắp xếp theo thứ tự:

select * from TopOrderedView; -- Ordered 10 line summary in 5s

Đối với trường hợp tương tự với một vị ngữ mạnh:

select * from TopOrderedView where <condition>; -- Ordered 2 line summary in still 5s

Nó vẫn mất cùng một lượng thời gian vì top / order bằng cách chặn vị từ không được chạy trước đó trong đường ống. Điều này có thể khiến các hàng không cần thiết được xử lý và kế hoạch sẽ tương tự như các hàng không có vị ngữ.

Việc đẩy có nên xảy ra trước khi đặt hàng thực sự là một lựa chọn của nhà phát triển và có thể thay đổi câu trả lời hay không. Thông thường đẩy là ý định hợp lý.

Sử dụng "top 100 phần trăm" một cách hợp lý cho phép đẩy vị ngữ tuy nhiên việc triển khai không may bỏ qua "thứ tự" cho trường hợp này và đánh bại ý định.

Đối với các trường hợp sử dụng thực tế, một thỏa hiệp tốt đẹp sẽ là cho động cơ thực hiện "trật tự bằng cách kéo". Điều này sẽ cho phép "thứ tự theo" được chỉ định trong chế độ xem (với 100 phần trăm hoặc không có đỉnh) và thứ tự đó chỉ được sử dụng nếu chế độ xem được chọn trực tiếp, không có thứ tự rõ ràng bởi, không tham gia, không tổng hợp, không tổng hợp xem chuỗi, vv Cả hai trường hợp được liệt kê ở trên có thể được hỗ trợ bởi mô hình đơn giản này.


-6

bạn có thể tạo chế độ xem theo thứ tự và giữ nguyên thứ tự khi được truy vấn sau:

chọn 99.999999999999 phần trăm hàng đầu * từ ..... đặt hàng trước


1
Tại sao không chỉ SELECT TOP 100 PERCENT ...?
Max Vernon

2
@Max có thể tương tự như thủ thuật này - điều đó không làm cho nó trở thành một ý tưởng tốt.
Aaron Bertrand

Đồng ý, @AaronBertrand - chỉ cần lưu ý rằng không cần sử dụng 99.99999999999 :-)
Max Vernon
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.