Tối ưu hóa giới hạn mysql

Nếu bạn chỉ cần một số hàng cụ thể từ một tập hợp kết quả, hãy sử dụng mệnh đề LIMIT trong truy vấn, thay vì tìm nạp toàn bộ tập hợp kết quả và loại bỏ dữ liệu bổ sung

MySQL đôi khi tối ưu hóa truy vấn có mệnh đề

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+
0 và không có mệnh đề
mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+
1

  • Nếu bạn chỉ chọn một vài hàng có LIMIT, MySQL sẽ sử dụng các chỉ mục trong một số trường hợp khi thông thường nó muốn thực hiện quét toàn bộ bảng

  • Nếu bạn kết hợp

    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    0 với
    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    4, MySQL sẽ ngừng sắp xếp ngay khi tìm thấy
    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    5 hàng đầu tiên của kết quả được sắp xếp, thay vì sắp xếp toàn bộ kết quả. Nếu đặt hàng được thực hiện bằng cách sử dụng một chỉ mục, điều này rất nhanh. Nếu phải thực hiện sắp xếp tệp, thì tất cả các hàng khớp với truy vấn không có mệnh đề LIMIT sẽ được chọn và hầu hết hoặc tất cả chúng đều được sắp xếp, trước khi tìm thấy
    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    5 đầu tiên. Sau khi tìm thấy các hàng ban đầu, MySQL không sắp xếp bất kỳ phần còn lại nào của tập kết quả

    Một biểu hiện của hành vi này là một truy vấn

    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    4 có và không có LIMIT có thể trả về các hàng theo thứ tự khác, như được mô tả sau trong phần này

  • Nếu bạn kết hợp

    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    0 với
    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    5, MySQL sẽ dừng ngay khi tìm thấy
    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    5 hàng duy nhất

  • Trong một số trường hợp, một

    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    7 có thể được giải quyết bằng cách đọc chỉ mục theo thứ tự (hoặc thực hiện sắp xếp trên chỉ mục), sau đó tính toán tóm tắt cho đến khi giá trị chỉ mục thay đổi. Trong trường hợp này,
    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    0 không tính toán bất kỳ giá trị
    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    7 không cần thiết nào

  • Ngay sau khi MySQL đã gửi số lượng hàng cần thiết cho máy khách, nó sẽ hủy truy vấn trừ khi bạn đang sử dụng

    mysql> SELECT * FROM ratings ORDER BY category, id;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  3 |        2 |    3.7 |
    |  4 |        2 |    3.5 |
    |  6 |        2 |    3.5 |
    |  2 |        3 |    5.0 |
    |  7 |        3 |    2.7 |
    +----+----------+--------+
    
    mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  3 |        2 |    3.7 |
    |  4 |        2 |    3.5 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    0. Trong trường hợp đó, số lượng hàng có thể được truy xuất bằng
    mysql> SELECT * FROM ratings ORDER BY category, id;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  3 |        2 |    3.7 |
    |  4 |        2 |    3.5 |
    |  6 |        2 |    3.5 |
    |  2 |        3 |    5.0 |
    |  7 |        3 |    2.7 |
    +----+----------+--------+
    
    mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  3 |        2 |    3.7 |
    |  4 |        2 |    3.5 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    1. Xem Phần 12. 16, “Chức năng thông tin”

  • mysql> SELECT * FROM ratings ORDER BY category, id;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  3 |        2 |    3.7 |
    |  4 |        2 |    3.5 |
    |  6 |        2 |    3.5 |
    |  2 |        3 |    5.0 |
    |  7 |        3 |    2.7 |
    +----+----------+--------+
    
    mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  3 |        2 |    3.7 |
    |  4 |        2 |    3.5 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    2 nhanh chóng trả về một tập rỗng. Điều này có thể hữu ích để kiểm tra tính hợp lệ của một truy vấn. Nó cũng có thể được sử dụng để có được các loại cột kết quả trong các ứng dụng sử dụng API MySQL để cung cấp siêu dữ liệu tập hợp kết quả. Với chương trình mysql client, bạn có thể sử dụng tùy chọn hiển thị các kiểu cột kết quả

  • Nếu máy chủ sử dụng các bảng tạm thời để giải quyết một truy vấn, nó sẽ sử dụng mệnh đề

    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    0 để tính toán dung lượng cần thiết

  • Nếu một chỉ mục không được sử dụng cho

    mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  4 |        2 |    3.5 |
    |  3 |        2 |    3.7 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    4 nhưng cũng có mệnh đề LIMIT, trình tối ưu hóa có thể tránh sử dụng tệp hợp nhất và sắp xếp các hàng trong bộ nhớ bằng cách sử dụng thao tác
    mysql> SELECT * FROM ratings ORDER BY category, id;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  3 |        2 |    3.7 |
    |  4 |        2 |    3.5 |
    |  6 |        2 |    3.5 |
    |  2 |        3 |    5.0 |
    |  7 |        3 |    2.7 |
    +----+----------+--------+
    
    mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;
    +----+----------+--------+
    | id | category | rating |
    +----+----------+--------+
    |  1 |        1 |    4.5 |
    |  5 |        1 |    3.2 |
    |  3 |        2 |    3.7 |
    |  4 |        2 |    3.5 |
    |  6 |        2 |    3.5 |
    +----+----------+--------+
    
    7 trong bộ nhớ

Nếu nhiều hàng có các giá trị giống hệt nhau trong các cột

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+
4, thì máy chủ có thể tự do trả lại các hàng đó theo bất kỳ thứ tự nào và có thể thực hiện khác đi tùy thuộc vào kế hoạch thực hiện tổng thể. Nói cách khác, thứ tự sắp xếp của các hàng đó là không xác định đối với các cột không có thứ tự

Một yếu tố ảnh hưởng đến kế hoạch thực hiện là LIMIT, vì vậy một truy vấn

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+
4 có và không có LIMIT có thể trả về các hàng theo các thứ tự khác nhau. Xem xét truy vấn này, được sắp xếp theo cột LIMIT2 nhưng không xác định đối với cột LIMIT3 và LIMIT4

mysql> SELECT * FROM ratings ORDER BY category;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  3 |        2 |    3.7 |
|  4 |        2 |    3.5 |
|  6 |        2 |    3.5 |
|  2 |        3 |    5.0 |
|  7 |        3 |    2.7 |
+----+----------+--------+

Việc bao gồm LIMIT có thể ảnh hưởng đến thứ tự các hàng trong mỗi giá trị LIMIT2. Ví dụ: đây là kết quả truy vấn hợp lệ

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+

Trong mỗi trường hợp, các hàng được sắp xếp theo cột

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+
4, đây là tất cả những gì được yêu cầu theo tiêu chuẩn SQL

Nếu điều quan trọng là đảm bảo thứ tự hàng giống nhau có và không có LIMIT, hãy bao gồm các cột bổ sung trong mệnh đề

mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
|  1 |        1 |    4.5 |
|  5 |        1 |    3.2 |
|  4 |        2 |    3.5 |
|  3 |        2 |    3.7 |
|  6 |        2 |    3.5 |
+----+----------+--------+
4 để làm cho thứ tự trở nên xác định. Ví dụ: nếu giá trị LIMIT3 là duy nhất, bạn có thể tạo các hàng cho giá trị LIMIT2 nhất định xuất hiện theo thứ tự LIMIT3 bằng cách sắp xếp như sau