2009-08-09 32 views
29

Đây là câu hỏi mà tôi đã có mãi mãi.Chỉ số MySQL và đặt hàng

Theo như tôi biết thứ tự các chỉ số quan trọng. Vì vậy, một chỉ mục như [first_name, last_name] không giống như [last_name, first_name], phải không?

Nếu tôi chỉ xác định chỉ số đầu tiên, điều đó có nghĩa rằng nó sẽ chỉ được sử dụng cho

SELECT * FROM table WHERE first_name="john" AND last_name="doe"; 

và không cho

SELECT * FROM table WHERE last_name="doe" AND first_name="john"; 

Kể từ khi tôi đang sử dụng một ORM, tôi không có ý tưởng trong thứ tự các cột này sẽ được gọi. Điều đó có nghĩa là tôi phải thêm các chỉ số trên tất cả các hoán vị? Đó là doable nếu tôi có một chỉ số 2 cột, nhưng những gì sẽ xảy ra nếu chỉ số của tôi là trên 3 hoặc 4 cột?

Trả lời

44

Thứ tự chỉ mục quan trọng khi điều kiện truy vấn của bạn chỉ áp dụng cho PHẦN của chỉ mục. Xem xét:

  1. SELECT * FROM table WHERE first_name="john" AND last_name="doe"

  2. SELECT * FROM table WHERE first_name="john"

  3. SELECT * FROM table WHERE last_name="doe"

Nếu chỉ số của bạn là (first_name, last_name) truy vấn 1 và 2 sẽ sử dụng nó, truy vấn # 3 won 't. Nếu chỉ mục của bạn là (last_name, first_name) các truy vấn 1 và 3 sẽ sử dụng, truy vấn số 2 sẽ không. Thay đổi thứ tự điều kiện trong mệnh đề WHERE không có hiệu lực trong cả hai trường hợp.

Cụ thể here

Cập nhật:
Trong trường hợp ở trên là không rõ ràng - MySQL chỉ có thể sử dụng một chỉ số nếu các cột trong điều kiện truy vấn tạo thành một tiền tố tận cùng bên trái của chỉ số. Truy vấn # 2 ở trên không thể sử dụng chỉ mục (last_name, first_name) vì chỉ dựa trên first_namefirst_name KHÔNG phải là tiền tố ngoài cùng bên trái của chỉ mục (last_name, first_name).

Thứ tự các điều kiện WITHIN truy vấn không quan trọng; truy vấn số 1 ở trên sẽ có thể sử dụng (last_name, first_name) chỉ số tốt vì các điều kiện của nó là first_namelast_name và được lấy cùng nhau, chúng tạo thành tiền tố ngoài cùng bên trái (last_name, first_name).

+0

Vì vậy, tôi đoán SELECT * FROM table WHERE last_name = "doe" AND first_name = "john" sẽ không? Nếu trường hợp đó xảy ra, vì tất cả các tòa nhà truy vấn bị ẩn bởi ORM của tôi, tôi có thể phải xác định 2 chỉ số ... thực sự hút, vì tôi có chỉ mục trên 3 cột để xác định ... –

+1

Không, bạn đã hiểu lầm. WHERE 'last_name' =" doe "AND' first_name' = "john" truy vấn sẽ sử dụng chỉ số ('first_name',' last_name') hoặc ('last_name',' first_name') chỉ tốt. – ChssPly76

+0

Một câu hỏi: đối với một truy vấn có 2 điều kiện VÀ, nó có quan trọng, tốc độ khôn ngoan, nó chỉ số là "đảo ngược" so với các điều kiện trong truy vấn, hay không? Hoặc nó phụ thuộc vào cardinality của những cột? – Mihai

5

ChssPly76 đúng là thứ tự biểu thức boolean không khớp với thứ tự các cột trong chỉ mục. Toán tử Boolean là commutative và trình tối ưu hóa MySQL đủ thông minh để biết cách khớp biểu thức với chỉ mục trong hầu hết các trường hợp.

Tôi cũng muốn thêm rằng bạn nên tìm hiểu cách sử dụng tính năng EXPLAIN của MySQL để bạn có thể tự mình xem chỉ mục nào trình tối ưu hóa sẽ chọn cho một truy vấn nhất định.

+2

+1 để giải thích. – Petrogad

+0

MySQL Workbench hiển thị một biểu diễn đồ họa của thông tin 'EXPLAIN' trong' Kế hoạch thực thi'. –

2

Tại sao không mở rộng câu trả lời một chút để làm cho mọi thứ hoàn toàn rõ ràng cùng một lúc.

Nếu bảng có chỉ mục nhiều cột, bất kỳ tiền tố ngoài cùng bên trái nào của chỉ mục có thể được trình tối ưu hóa sử dụng để tìm các hàng. Ví dụ: nếu bạn có chỉ mục ba cột trên (col1, col2, col3), bạn đã lập chỉ mục các khả năng tìm kiếm trên (col1), (col1, col2)(col1, col2, col3).

MySQL không thể sử dụng chỉ mục nếu các cột không tạo thành tiền tố ngoài cùng bên trái của chỉ mục. Giả sử bạn có các câu lệnh SELECT được hiển thị ở đây:

SELECT * FROM tbl_name WHERE col1=val1; 
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2; 

SELECT * FROM tbl_name WHERE col2=val2; 
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3; 

Nếu chỉ mục tồn tại trên (col1, col2, col3), chỉ hai truy vấn đầu tiên sử dụng chỉ mục. Truy vấn thứ ba và thứ tư liên quan đến các cột được lập chỉ mục, nhưng (col2)(col2, col3) không phải là tiền tố ngoài cùng bên trái của (col1, col2, col3). - MySQL dev

Các vấn đề liên quan