2011-07-27 15 views
7

Nếu bảng User của tôi có một số trường có thể truy vấn (ví dụ: DepartmentId, GroupId, RoleId), nó sẽ tạo ra bất kỳ sự khác biệt về tốc độ nào nếu tôi tạo chỉ mục cho từng kết hợp của các trường đó?Có cần phải có chỉ mục trên mọi kết hợp các trường có thể truy vấn trong bảng SQL để tối ưu hóa hiệu suất không?

Bằng "truy vấn", tôi đang đề cập đến màn hình truy vấn nơi người dùng cuối có thể chọn bản ghi dựa trên Bộ, Nhóm hoặc Vai trò bằng cách chọn từ menu thả xuống.

Hiện tại, tôi có chỉ mục trên DepartmentId, GroupId và RoleId. Đó là một chỉ mục không duy nhất cho mỗi trường.

Nếu một người dùng cuối lựa chọn "bất cứ ai trong nhóm B", SQL trông giống như:

select * from User where GroupId = 2 

Có một chỉ mục trên GROUPID nên tốc độ đó lên.

Nhưng nếu người dùng cuối chọn "bất cứ ai trong nhóm B và trong Role C", SQL sẽ trông như thế này:

select * from User where GroupId = 2 and RoleId = 3 

Có chỉ số trên GROUPID và Id vai trò cá nhân có thể không thực hiện bất kỳ sự khác biệt, phải không?

Chỉ mục tốt hơn cho tìm kiếm đó sẽ là nếu tôi có một chỉ mục trải rộng cả hai GroupId và RoleId.

Nhưng nếu đúng như vậy, điều đó có nghĩa là tôi sẽ cần có chỉ mục cho mọi kết hợp các trường có thể truy vấn. Vì vậy, tôi sẽ cần tất cả các chỉ số:

  • DepartmentId
  • groupId
  • Id vai trò
  • DepartmentId và groupId
  • DepartmentId và Id vai trò
  • groupId và Id vai trò
  • cục Id, groupId và Id vai trò

Có ai có thể làm sáng tỏ điều này không? Tôi đang sử dụng MySQL nếu điều đó tạo nên sự khác biệt.

+0

Hãy nhớ rằng thứ tự của các cột quan trọng - (GroupId, RoleId) là * không * giống như (RoleId, GroupId). Vì vậy, danh sách của bạn thiếu một số chỉ dẫn bổ sung.Nếu không, nhận xét của @ Joe về việc hợp nhất chỉ mục là tốt (DB2 cũng sử dụng điều này, để có hiệu quả tốt). –

Trả lời

7

Chỉ mục nhiều cột có thể được sử dụng cho bất kỳ tiền tố bên trái nào của chỉ mục đó. Vì vậy, một chỉ số trên (A, B, C) có thể được sử dụng cho các truy vấn trên (A), (A, B) và (A, B, C), nhưng nó không thể, ví dụ, được sử dụng cho các truy vấn trên (B)) hoặc (B, C).

Nếu các cột được lập chỉ mục riêng lẻ, MySQL (5.0 hoặc mới hơn) cũng có thể sử dụng Index Merge Optimization.

+0

Thú vị. Vì vậy, miễn là các tham số nơi được xây dựng theo cùng một thứ tự mỗi lần, tôi chỉ cần (A, B, C), (A, C), (B, C) và (C) là bốn chỉ số tổng thể bao gồm tất cả các căn cứ. – sohtimsso1970

+1

@ sohtimsso1970: Thứ tự không quan trọng bằng SQL là ngôn ngữ khai báo. Đó là: 'WHERE A = 1 AND B = 2' và 'WHERE B = 2 AND A = 1' là giống nhau và cả hai có thể sử dụng chỉ mục trên (A, B). –

+0

Cảm ơn bạn đã làm rõ. Tôi suy ra từ một số người bình luận khác rằng thứ tự của các trường trong mệnh đề where cũng quan trọng. Nếu thứ tự của các trường chỉ số quan trọng nhưng mệnh đề where không, thì thực tế nói thứ tự của các trường chỉ mục cũng không quan trọng. – sohtimsso1970

1

Điều tôi thấy là tốt nhất nên lập chỉ mục mọi thứ mà người dùng sẽ tìm kiếm. Tôi đã thực sự tìm thấy hiệu suất tốt hơn bằng cách tạo các chỉ mục với nhiều cột nếu tìm kiếm các cột đó sẽ được thực thi. Ví dụ: nếu ai đó có thể tìm kiếm cả hai vai trò và nhóm cùng một lúc, việc có chỉ mục với cả hai cột đó thực sự sẽ nhanh hơn một chút so với chỉ có một chỉ mục trên mỗi cột. Tuy nhiên, việc có chỉ mục trên mỗi cột có thể truy vấn vẫn có thể tốt, vì bạn có thể bỏ lỡ kết hợp các cột.

Cân nhắc chính là xem số lượng chỉ mục sẽ mất bao nhiêu. Vì các cột này là các trường số nguyên nên nó không phải là một vấn đề lớn. Một chút thời gian tạo chỉ mục có thể gặt hái những lợi ích đáng kể.

Điều tốt nhất cần làm là thử nghiệm. Thực hiện tìm kiếm trên nhiều cột và thời gian, sau đó thêm chỉ mục kết hợp và chạy lại.

2

Trải nghiệm của tôi là với SQL Server thay vì mysql và có thể điều này tạo nên sự khác biệt. Tuy nhiên, nói chung, động cơ có thể sử dụng nhiều chỉ mục trên một truy vấn. Mặc dù có những lợi ích chắc chắn để có một chỉ mục đơn toàn diện hơn (nó cung cấp một tăng lớn hơn, đặc biệt nếu nó tạo thành một chỉ số bao phủ), bạn vẫn sẽ có lợi từ việc sử dụng chỉ mục trên mỗi trường truy vấn.

Hơn nữa, hãy nhớ rằng mỗi chỉ mục phải được duy trì riêng biệt, vì vậy bạn sẽ bị giảm hiệu suất khi ghi các hoạt động khi số chỉ mục của bạn tăng lên.

0

Xóa tất cả các chỉ mục và chạy các câu lệnh CRUD đối với bảng bằng công cụ miễn phí có tên "Trình thám hiểm kế hoạch gửi SQL".

Nó sẽ cho bạn thấy chỉ mục nào là cần thiết.

Chỉ mục được tạo dựa trên CRUD chứ không phải trên bảng.

+1

Cảm ơn lời khuyên, nhưng phần mềm đó dường như chỉ hoạt động cho SQL Server. – sohtimsso1970

+0

Có nhiều công cụ sẽ thực hiện chính xác như sau: http://www.mysql.com/products/enterprise/query.html –

3

Nói chung, chỉ số sẽ tăng tốc độ truy vấn, nhưng giảm tốc độ chèn/cập nhật, và tiết kiệm dung lượng đĩa/overhead. Vì vậy, hãy hỏi xem bạn có nên lập chỉ mục từng kết hợp các cột giống như hỏi xem bạn có nên tối ưu hóa mọi chức năng trong mã của mình hay không. Nó có thể làm cho một số điều nhanh hơn, hoặc nó chỉ có thể giúp đỡ, và nó có thể chỉ đau hơn nó giúp.

Hiệu quả của chỉ số phụ thuộc vào:

  • Tỷ lệ chọn vs chèn và cập nhật
  • Các chi tiết cụ thể của các truy vấn SELECT, và liệu họ có sử dụng câu lệnh JOIN
  • Kích thước của bảng được lập chỉ mục
  • RAM và tốc độ xử lý
  • Cài đặt MySQL bao nhiêu RAM để sử dụng, v.v.

Vì vậy, thật khó để đưa ra câu trả lời chung. Lời khuyên cơ bản về âm thanh sẽ là: Thêm chỉ mục nếu truy vấn quá chậm. Và hãy nhớ sử dụng GIẢI THÍCH để xem các chỉ mục cần thêm. Lưu ý rằng đây là loại giống như phiên bản cơ sở dữ liệu của lời khuyên chung: Hồ sơ ứng dụng của bạn trước khi dành thời gian tối ưu hóa.

2

Tạo chỉ mục cẩn thận! Tôi khuyên bạn nên thu thập số liệu thống kê truy vấn và quyết định cột nào thường được sử dụng trong khi tìm kiếm để bạn có thể tạo chỉ mục Clustered trên cột cụ thể này (dù sao khi bạn tạo chỉ mục trên nhiều cột - dữ liệu vật lý có thể được đặt chỉ bằng một cột)

Cũng xin lưu ý rằng chỉ mục Clustered có thể làm giảm đáng kể hiệu suất của các truy vấn UPDATE/INSERT/DELETE do nó làm cho dữ liệu vật lý sắp xếp lại.

+0

Chỉ có thể có một chỉ mục nhóm trên bảng. – RocketR

+0

yep Tôi biết điều này – sll

+0

Tôi phải hiểu bạn sai về _each chỉ mục Clustered mới_, xin lỗi. – RocketR

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