MIN / MAX so với ORDER BY và LIMIT


99

Trong số các truy vấn sau đây, bạn sẽ xem xét phương pháp nào tốt hơn? Lý do của bạn là gì (hiệu quả mã, khả năng bảo trì tốt hơn, ít WTFery hơn) ...

SELECT MIN(`field`)
FROM `tbl`;

SELECT `field`
FROM `tbl`
ORDER BY `field`
LIMIT 1;

Câu trả lời:


125

Trong trường hợp xấu nhất, khi bạn đang xem một trường không được lập chỉ mục, việc sử dụng MIN()yêu cầu một lần chuyển đầy đủ của bảng. Sử dụng SORTLIMITyêu cầu một tập tin. Nếu chạy với một bàn lớn, có thể sẽ có sự khác biệt đáng kể về hiệu suất đạt được. Là một điểm dữ liệu vô nghĩa, MIN()mất 0,36 giây SORTLIMIT mất 0,84 giây so với bảng 106.000 hàng trên máy chủ nhà phát triển của tôi.

Tuy nhiên, nếu bạn đang xem một cột được lập chỉ mục, thì sự khác biệt sẽ khó nhận thấy hơn (điểm dữ liệu vô nghĩa là 0,00 giây trong cả hai trường hợp). Tuy nhiên, nhìn vào đầu ra của giải thích, có vẻ như MIN()có thể chỉ cần lấy giá trị nhỏ nhất từ ​​chỉ mục (các hàng 'Chọn bảng được tối ưu hóa' và 'NULL') trong khi SORTLIMITvẫn cần thực hiện duyệt chỉ mục có thứ tự (106.000 hàng). Tác động hiệu suất thực tế có lẽ là không đáng kể.

Có vẻ như đây MIN()là cách để đi - nó nhanh hơn trong trường hợp xấu nhất, không thể phân biệt trong trường hợp tốt nhất, là SQL chuẩn và thể hiện rõ ràng nhất giá trị bạn đang cố gắng đạt được. Như mson đã đề cập, trường hợp duy nhất mà có vẻ như việc sử dụng SORTLIMITmong muốn sẽ là, như mson đã đề cập, khi bạn đang viết một phép toán chung tìm giá trị N trên cùng hoặc dưới cùng từ các cột tùy ý và không đáng để viết ra phép toán trường hợp đặc biệt.


7
o (n) cho một pass duy nhất so với 0 (nlogn) để phân loại
Abhishek Iyer

1
@AbhishekIyer bạn hoàn toàn đúng, nhưng tôi sẽ thêm "trong trường hợp xấu nhất cho trường chưa lập chỉ mục".
dmikam

Phần đó về trường hợp không lập chỉ mục tồi tệ nhất là sai. Bạn luôn cần quét toàn bộ, làm thế nào khác bạn biết đó là tối thiểu hoặc tối đa? Nó không giống như bạn đang quét và giá trị hét lên: "Này, cuối cùng bạn đã tìm thấy tôi! Tôi là Jack, tối đa!".
Robo Robok

Trong một thử nghiệm với một bảng được lập chỉ mục với 470 triệu hàng, cả hai truy vấn đều mất 0,00 giây. Tuy nhiên, nếu chúng tôi thêm vào các truy vấn một bộ lọc "WHERE field2 = x", thì truy vấn với LIMIT vẫn mất 0,00 giây và truy vấn với MIN mất 0,21 giây.
Antonio Cañas Vargas

12
SELECT MIN(`field`)
FROM `tbl`;

Đơn giản vì nó tương thích ANSI. Giới hạn 1 dành riêng cho MySql vì TOP là SQL Server.


Hầu hết DBMSes đã giới hạn / bù đắp hoặc tương đương, và nó được sử dụng trong phần lớn các ứng dụng tôi đã làm việc trên (không phải là một thay thế cho MIN, nhưng đối với các mục đích khác như pagination.)
finnw

@finnw - Tôi đồng ý, nhưng ví dụ của người hỏi là so sánh giới hạn với min một cách rõ ràng.
Otávio Décio

9

Như msonSean McSomething có ra nhọn, MIN là một lợi thế.

Một lý do khác mà ORDER BY + LIMIT hữu ích là nếu bạn muốn nhận giá trị của một cột khác với cột MIN.

Thí dụ:

SELECT some_other_field, field
FROM tbl
ORDER BY field
LIMIT 1

4

Tôi nghĩ câu trả lời phụ thuộc vào những gì bạn đang làm.

Nếu bạn có một truy vấn tắt và mục đích đơn giản như bạn đã chỉ định, chọn min (trường) là phù hợp hơn.

Tuy nhiên, thông thường các loại yêu cầu này thay đổi thành - lấy kết quả thứ n hàng đầu, lấy kết quả thứ n - thứ, v.v.

Tôi không nghĩ rằng đó là một ý tưởng quá khủng khiếp khi cam kết với cơ sở dữ liệu bạn đã chọn. Thay đổi dbs không nên được thực hiện nhẹ nhàng và phải sửa đổi là cái giá bạn phải trả khi thực hiện động thái này.

Tại sao lại giới hạn bản thân ngay bây giờ, vì những cơn đau mà bạn có thể cảm thấy hoặc không thể cảm thấy sau này?

Tôi nghĩ rằng thật tốt nếu duy trì ANSI nhiều nhất có thể, nhưng đó chỉ là phương châm ...


3

Với hiệu suất chấp nhận được, tôi sẽ sử dụng cái đầu tiên vì nó gần với ý định hơn về mặt ngữ nghĩa.
Nếu hiệu suất là một vấn đề, (Hầu hết các trình tối ưu hóa hiện đại sẽ tối ưu hóa theo tỷ lệ cả hai cho cùng một kế hoạch truy vấn, mặc dù bạn phải kiểm tra để xác minh điều đó) thì tất nhiên tôi sẽ sử dụng kế hoạch nhanh hơn.

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.