Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Thứ tự các trường trong mệnh đề WHERE có ảnh hưởng đến hiệu suất trong MySQL không?

SQL được thiết kế để trở thành một ngôn ngữ khai báo, không phải là một ngôn ngữ thủ tục. Vì vậy, trình tối ưu hóa truy vấn sẽ không xem xét thứ tự của các vị từ mệnh đề where trong việc xác định cách áp dụng chúng.

Có lẽ tôi sẽ đơn giản hóa quá mức cuộc thảo luận sau đây về trình tối ưu hóa truy vấn SQL. Tôi đã viết một năm trước, dọc theo những dòng này (thật là vui!). Nếu bạn thực sự muốn tìm hiểu sâu về tối ưu hóa truy vấn hiện đại, hãy xem Điều chỉnh SQL , từ O'Reilly.

Trong một trình tối ưu hóa truy vấn SQL đơn giản, câu lệnh SQL trước tiên được biên dịch thành một cây đại số quan hệ các hoạt động. Mỗi hoạt động này lấy một hoặc nhiều bảng làm đầu vào và tạo ra một bảng khác làm đầu ra. Quét là quá trình quét tuần tự đọc một bảng từ cơ sở dữ liệu. Sắp xếp tạo ra một bảng được sắp xếp. Chọn tạo ra một bảng có các hàng được chọn từ một bảng khác theo một số điều kiện lựa chọn. Dự án tạo ra một bảng chỉ có một số cột nhất định của bảng khác. Sản phẩm chéo lấy hai bảng và tạo ra một bảng bao gồm mọi ghép nối có thể hình dung được của các hàng của chúng.

Thật khó hiểu, mệnh đề SQL SELECT được biên dịch thành một Dự án đại số quan hệ , trong khi mệnh đề WHERE chuyển thành đại số quan hệ Chọn . Mệnh đề FROM chuyển thành một hoặc nhiều Tham gia , mỗi người lấy hai bảng vào và tạo ra một bảng. Có các phép toán đại số quan hệ khác liên quan đến tập hợp, giao, hiệu và thành viên, nhưng hãy giữ điều này đơn giản.

Cây này thực sự cần được tối ưu hóa. Ví dụ:nếu bạn có:

select E.name, D.name 
from Employee E, Department D 
where E.id = 123456 and E.dept_id = D.dept_id

với 5.000 nhân viên trong 500 phòng ban, việc thực hiện một cây chưa được tối ưu hóa sẽ tạo ra tất cả các kết hợp có thể có của một Nhân viên và một Phòng ban (a Sản phẩm chéo ) và sau đó Chọn chỉ ra một sự kết hợp cần thiết. Quét của Nhân viên sẽ tạo ra một bảng ghi 5.000, bảng Quét of Department sẽ tạo ra một bảng ghi 500, Sản phẩm chéo trong số hai bảng đó sẽ tạo ra một bảng ghi 2.500.000 và nút Chọn trên E.id sẽ lấy bảng ghi 2.500.000 đó và loại bỏ tất cả trừ một bản ghi mà bạn muốn.

[Tất nhiên, bộ xử lý truy vấn thực sự sẽ cố gắng không hiện thực hóa tất cả các bảng trung gian này trong bộ nhớ.]

Vì vậy, trình tối ưu hóa truy vấn đi trên cây và áp dụng các tối ưu hóa khác nhau. Một là chia tay từng Chọn thành một chuỗi Lựa chọn , một cho mỗi Chọn ban đầu các điều kiện cấp cao nhất, những điều kiện và chỉnh sửa cùng nhau. (Đây được gọi là "dạng chuẩn liên hợp".) Sau đó, Chọn riêng lẻ được di chuyển xung quanh trong cây và được hợp nhất với các phép toán đại số quan hệ khác để tạo thành các phép toán hiệu quả hơn.

Trong ví dụ trên, trình tối ưu hóa trước tiên sẽ đẩy nút Chọn trên E.id =123456 xuống dưới Sản phẩm chéo đắt tiền hoạt động. Điều này có nghĩa là Sản phẩm chéo chỉ sản xuất 500 hàng (một hàng cho mỗi sự kết hợp của nhân viên đó và một bộ phận). Sau đó, cấp cao nhất Chọn for E.dept_id =D.dept_id lọc ra 499 hàng không mong muốn. Không tệ.

Nếu có một chỉ mục trên trường id của Nhân viên, thì trình tối ưu hóa có thể kết hợp Quét của Nhân viên với Chọn trên E.id =123456 để tạo chỉ mục nhanh Tra cứu . Điều này có nghĩa là chỉ một hàng Nhân viên được đọc vào bộ nhớ từ đĩa thay vì 5.000. Mọi thứ đang tìm kiếm.

Tối ưu hóa chính cuối cùng là thực hiện Chọn trên E.dept_id =D.dept_id và kết hợp nó với Sản phẩm chéo . Điều này biến nó thành một đại số quan hệ Equijoin hoạt động. Điều này không làm được gì nhiều. Nhưng nếu có một chỉ mục trên Department.dept_id, thì trình tự cấp thấp hơn Quét của Bộ cho ăn Equijoin có thể được chuyển thành một chỉ mục rất nhanh Tra cứu trong hồ sơ Bộ phận của một nhân viên của chúng tôi.

Tối ưu hóa ít hơn liên quan đến việc đẩy Dự án hoạt động giảm. Nếu cấp cao nhất của truy vấn của bạn chỉ cần E.name và D.name và các điều kiện cần E.id, E.dept_id và D.dept_id, thì Quét các hoạt động không phải tạo bảng trung gian với tất cả các cột khác, tiết kiệm không gian trong quá trình thực thi truy vấn. Chúng tôi đã biến một truy vấn chậm kinh khủng thành hai tra cứu chỉ mục chứ không phải nhiều thứ khác.

Tìm hiểu thêm về câu hỏi ban đầu, giả sử bạn đã có:

select E.name 
from Employee E 
where E.age > 21 and E.state = 'Delaware'

Cây đại số quan hệ chưa được tối ưu hóa, khi được thực thi, sẽ quét 5.000 nhân viên và tạo ra 126 nhân viên trong Delaware cũ hơn 21. Trình tối ưu hóa truy vấn cũng có một số ý tưởng sơ bộ về các giá trị trong cơ sở dữ liệu. Nó có thể biết rằng cột E.state có 14 trạng thái mà công ty có địa điểm và một số điều về các bản phân phối của E.age. Vì vậy, trước tiên nó xem liệu một trong hai trường có được lập chỉ mục hay không. Nếu có E.state, sẽ hợp lý khi sử dụng chỉ mục đó để chỉ chọn ra một số lượng nhỏ nhân viên mà bộ xử lý truy vấn nghi ngờ đang ở Delaware dựa trên số liệu thống kê được tính toán gần đây nhất của nó. Nếu chỉ có E.age, bộ xử lý truy vấn có thể quyết định rằng điều đó không đáng, vì 96% tổng số nhân viên từ 22 tuổi trở lên. Vì vậy, nếu E.state được lập chỉ mục, bộ xử lý truy vấn của chúng tôi sẽ phá vỡ Chọn và hợp nhất E.state ='Delaware' với Scan để biến nó thành một Quét chỉ mục hiệu quả hơn nhiều .

Giả sử trong ví dụ này không có chỉ mục nào trên E.state và E.age. Chọn kết hợp hoạt động diễn ra sau khi "Quét" nhân viên tuần tự. Nó có tạo ra sự khác biệt với điều kiện trong Chọn được thực hiện đầu tiên? Có lẽ không phải là một vấn đề lớn. Bộ xử lý truy vấn có thể để chúng theo thứ tự ban đầu trong câu lệnh SQL hoặc có thể phức tạp hơn một chút và xem xét chi phí dự kiến. Từ các số liệu thống kê, một lần nữa sẽ thấy rằng điều kiện E.state ='Delaware' nên có tính chọn lọc cao hơn, vì vậy nó sẽ đảo ngược các điều kiện và thực hiện điều đó trước, để chỉ có 126 E.age> 21 so sánh thay vì 5.000 . Hoặc có thể nhận ra rằng so sánh đẳng thức chuỗi đắt hơn nhiều so với so sánh số nguyên và để nguyên thứ tự.

Dù sao đi nữa, tất cả điều này đều rất phức tạp và thứ tự điều kiện cú pháp của bạn rất khó có thể tạo ra sự khác biệt. Tôi sẽ không lo lắng về điều đó trừ khi bạn gặp vấn đề về hiệu suất thực sự và nhà cung cấp cơ sở dữ liệu của bạn sử dụng thứ tự điều kiện như một gợi ý.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL - Sử dụng If Then Else trong MySQL UPDATE hoặc SELECT Queries

  2. Làm cách nào để đếm giá trị NULL trong MySQL?

  3. Số lượng SQL - không hoạt động

  4. Doctrine không tồn tại thực thể với các giá trị boolean và PDO ::ATTR_EMULATE_PREPARES =false trong Mysql

  5. varchar (255) so với tinytext / tinyblob và varchar (65535) so với blob / text