Tại sao sử dụng Chọn 100 Phần trăm Hàng đầu?


82

Tôi hiểu rằng trước SQL Server 2005 , bạn có thể "lừa" SQL Server để cho phép sử dụng một thứ tự theo định nghĩa dạng xem, bằng cách đưa TOP 100 PERCENTvào mệnh đề SELECT . Nhưng tôi đã thấy mã khác mà tôi đã kế thừa sử dụng SELECT TOP 100 PERCENT... trong các câu lệnh SQL động (được sử dụng trong ADO trong các ứng dụng ASP.NET , v.v.). Có lý do cho điều này? Không phải là kết quả giống như không bao gồm TOP 100 PERCENT?


5
có thể có một số cấu trúc tuyên bố đang diễn ra: "CHỌN HÀNG ĐẦU {0} PERCENT ..."
Michael Petrotta 26/10/09

Câu đầu tiên của bạn đã trở thành câu trả lời một trong những câu hỏi ẩn của tôi.
Muhammad Ashikuzzaman 10/02/19

Tôi sử dụng 99,9999999 PERCENT hàng đầu và nó luôn hoạt động. Nó đủ gần. Tôi có xu hướng thêm số '9' dựa trên số bản ghi dự kiến. Nhiều bản ghi hơn, nhiều hơn 9 và nó luôn hoạt động. Tôi đã sử dụng trên SQL 2008 đến SQL 2017.
pedi

Câu trả lời:


51

Nó được sử dụng để " vật liệu hóa trung gian (tìm kiếm của Google) "

Bài hay: Adam Machanic: Khám phá bí mật của quá trình vật chất hóa trung gian

Anh ấy thậm chí còn tạo ra một MS Connect để nó có thể được thực hiện theo cách gọn gàng hơn

Quan điểm của tôi là "vốn dĩ không tệ", nhưng đừng sử dụng nó trừ khi chắc chắn 100%. Vấn đề là, nó chỉ hoạt động tại thời điểm bạn làm điều đó và có thể không sau đó (cấp bản vá, lược đồ, chỉ mục, số lượng hàng, v.v.) ...

Ví dụ đã làm việc

Điều này có thể không thành công vì bạn không biết mọi thứ được đánh giá theo thứ tự nào

SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1 AND CAST(foo AS int) > 100

Và điều này cũng có thể thất bại vì

SELECT foo
FROM
    (SELECT foo From MyTable WHERE ISNUMERIC (foo) = 1) bar
WHERE
    CAST(foo AS int) > 100

Tuy nhiên, điều này không xảy ra trong SQL Server 2000. Truy vấn bên trong được đánh giá và phân phối:

SELECT foo
FROM
    (SELECT TOP 100 PERCENT foo From MyTable WHERE ISNUMERIC (foo) = 1 ORDER BY foo) bar
WHERE
    CAST(foo AS int) > 100

Lưu ý, điều này vẫn hoạt động trong SQL Server 2005

SELECT TOP 2000000000 ... ORDER BY...

Tại sao truy vấn thứ hai không thành công? Bởi vì truy vấn bên trong không (nhất thiết) được đánh giá đầy đủ?
Kenny Evitt, 18:13

Liên kết thứ hai đó giải thích tại sao việc tạo bảng tạm thời đôi khi dẫn đến cải thiện hiệu suất đáng kể!
Kenny Evitt,

41

TOP (100) PERCENT hoàn toàn vô nghĩa trong các phiên bản SQL Server gần đây và nó (cùng với ORDER BY tương ứng, trong trường hợp định nghĩa dạng xem hoặc bảng dẫn xuất) bị bộ xử lý truy vấn bỏ qua.

Bạn đúng rằng ngày xưa, nó có thể được sử dụng như một thủ thuật, nhưng ngay cả khi đó nó cũng không đáng tin cậy. Đáng buồn thay, một số công cụ đồ họa của Microsoft đã đưa điều khoản vô nghĩa này vào.

Về lý do tại sao điều này có thể xuất hiện trong SQL động, tôi không biết. Bạn đúng là không có lý do gì cho điều đó và kết quả vẫn như vậy nếu không có nó (và một lần nữa, trong trường hợp định nghĩa dạng xem hoặc bảng dẫn xuất, không có cả hai mệnh đề TOP và ORDER BY).


Điều này không đúng; xem liên kết này từ câu trả lời của @gbn để biết chi tiết.
Kenny Evitt,

3
Liên kết bạn tham chiếu không nói bất cứ điều gì về CHỌN ĐẦU (100) PERCENT .. ORDER BY, điều này là vô nghĩa. Liên kết đề cập đến việc sử dụng SELECT TOP (2147483647) .. ORDER BY. Hiện tại, trình tối ưu hóa SQL Server sẽ loại bỏ CHỌN ĐẦU (100) PERCENT .. ORDER BY, vì nó vô nghĩa. Sự kết hợp đó luôn xác định cùng một tập hợp các hàng là SELECT mà không có TOP / ORDER BY. Trình tối ưu hóa hiện không cố gắng xác định xem 2147483647 có bao gồm tất cả các hàng hay không, vì vậy nó không loại bỏ kết hợp TOP - ORDER BY trong trường hợp này.
Steve Kass

2
Liên kết thực sự đề cập đến TOP (100) PERCENT: "... Tôi có thể thử buộc thực hiện trung gian hóa bảng dẫn xuất, sans bảng tạm thời, bằng cách sử dụng TOP 100 PERCENT kết hợp với ORDER BY. Thật không may, nhóm tối ưu hóa truy vấn SQL Server đã quyết định rằng điều này không phải là ' không phải là một ý kiến ​​hay và trình tối ưu hóa hiện bỏ qua những nỗ lực như vậy. " Nó hỗ trợ bạn trên thực tế.
Kenny Evitt

Tôi sẽ hoàn tác phản đối của mình nếu có thể . [Nếu bạn chỉnh sửa câu trả lời của mình, tôi sẽ tán thành nó.]
Kenny Evitt

1
Có lẽ bạn đang bối rối vì tôi đã thay đổi quyết định; nhận xét đầu tiên của tôi là sai; bạn đúng.
Kenny Evitt

23

... cho phép sử dụng ORDER BY trong định nghĩa dạng xem.

Đó không phải là một ý tưởng hay. Một dạng xem không bao giờ được xác định ORDER BY.

ORDER BY có tác động đến hiệu suất - sử dụng nó để xem có nghĩa là ORDER BY sẽ xuất hiện trong kế hoạch giải thích. Nếu bạn có một truy vấn trong đó chế độ xem được kết hợp với bất kỳ thứ gì trong truy vấn ngay lập tức hoặc được tham chiếu trong chế độ xem nội tuyến (CTE / truy vấn phụ) - ORDER BY luôn chạy trước ORDER BY cuối cùng (giả sử nó đã được xác định). Không có lợi ích gì khi sắp xếp các hàng không phải là kết quả cuối cùng được đặt khi truy vấn không sử dụng TOP (hoặc LIMIT cho MySQL / Postgres).

Xem xét:

CREATE VIEW my_view AS
    SELECT i.item_id,
           i.item_description,
           it.item_type_description
      FROM ITEMS i
      JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
  ORDER BY i.item_description

...

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM my_view t
ORDER BY t.item_type_description

... tương đương với việc sử dụng:

  SELECT t.item_id,
         t.item_description,
         t.item_type_description
    FROM (SELECT i.item_id,
                 i.item_description,
                 it.item_type_description
            FROM ITEMS i
            JOIN ITEM_TYPES it ON it.item_type_id = i.item_type_id
        ORDER BY i.item_description) t
ORDER BY t.item_type_description

Điều này thật tệ vì:

  1. Ví dụ ban đầu là sắp xếp danh sách theo mô tả mặt hàng, sau đó sắp xếp lại danh sách dựa trên mô tả loại mặt hàng. Đó là tài nguyên lãng phí trong loại đầu tiên - chạy như vậy không có nghĩa là nó đang chạy:ORDER BY item_type_description, item_description
  2. Không rõ khung nhìn được sắp xếp theo thứ tự nào do đóng gói. Điều này không có nghĩa là bạn nên tạo nhiều dạng xem với các thứ tự sắp xếp khác nhau ...

6

Nếu không có ORDER BYmệnh đề thì TOP 100 PERCENTthừa. (Như bạn đã đề cập, đây là 'thủ thuật' với lượt xem)

[Hy vọng rằng trình tối ưu hóa sẽ tối ưu hóa điều này.]


5

Tôi đã thấy mã khác mà tôi đã kế thừa sử dụng SELECT TOP 100 PERCENT

Lý do cho điều này rất đơn giản: Enterprise Manager đã từng cố gắng tỏ ra hữu ích và định dạng mã của bạn để bao gồm điều này cho bạn. Không có ích gì khi cố gắng loại bỏ nó vì nó không thực sự gây hại gì và lần sau khi bạn thay đổi nó, EM sẽ chèn nó lại.


4

Không có lý do gì ngoài sự thờ ơ, tôi đoán vậy.

Các chuỗi truy vấn như vậy thường được tạo bởi một công cụ truy vấn đồ họa. Người dùng tham gia một số bảng, thêm bộ lọc, thứ tự sắp xếp và kiểm tra kết quả. Vì người dùng có thể muốn lưu truy vấn dưới dạng một dạng xem, nên công cụ sẽ thêm 100 PHẦN TRĂM HÀNG ĐẦU. Tuy nhiên, trong trường hợp này, người dùng sao chép SQL vào mã của mình, được tham số hóa mệnh đề WHERE và ẩn mọi thứ trong một lớp truy cập dữ liệu. Mất trí, khuất tầm nhìn.


1

Vui lòng thử phần dưới đây, Hy vọng nó sẽ hiệu quả với bạn.

      SELECT TOP
              ( SELECT COUNT(foo) 
                  From MyTable 
                 WHERE ISNUMERIC (foo) = 1) * 
                  FROM bar WITH(NOLOCK) 
              ORDER BY foo
                 WHERE CAST(foo AS int) > 100
               )

1

Lỗi nói lên tất cả ...

Msg 1033, Mức 15, Trạng thái 1, Chế độ xem thủ tục, Dòng 5 Mệnh đề ORDER BY không hợp lệ trong các dạng xem, hàm nội tuyến, bảng dẫn xuất, truy vấn con và biểu thức bảng thông thường, trừ khi TOP, OFFSET hoặc FOR XML cũng được chỉ định.

Không sử dụng TOP 100 PERCENT, sử dụng TOP n, trong đó N là số

100 PERCENT HÀNG ĐẦU (vì lý do tôi không biết) bị SQL Server VIEW (phiên bản đăng 2012) bỏ qua, nhưng tôi nghĩ MS đã giữ nó vì lý do cú pháp. TOP n tốt hơn và sẽ hoạt động bên trong một dạng xem và sắp xếp nó theo cách bạn muốn khi một dạng xem được sử dụng ban đầu, nhưng hãy cẩn thận .


0

Tôi giả sử rằng bạn có thể sử dụng một biến trong kết quả, nhưng ngoài việc nhận được ORDER BY mảnh trong một chế độ xem, bạn sẽ không thấy lợi ích khi nói rõ "100 PERCENT HÀNG ĐẦU":

declare @t int
set @t=100
select top (@t) percent * from tableOf

2
Câu hỏi Why use Select Top 100 Percentkhông phải là để có được một số lượng biến cho Phần trăm.
bummi

0

Chỉ cần thử điều này, nó giải thích nó khá nhiều. Bạn không thể tạo chế độ xem bằng ORDER BY trừ khi ...

CREATE VIEW v_Test
         AS
           SELECT name
             FROM sysobjects
         ORDER BY name
        GO

Msg 1033, Mức 15, Trạng thái 1, Chế độ xem thủ tục, Dòng 5 Mệnh đề ORDER BY không hợp lệ trong các dạng xem, hàm nội tuyến, bảng dẫn xuất, truy vấn con và biểu thức bảng thông thường, trừ khi TOP, OFFSET hoặc FOR XML cũng được chỉ định.

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.