Tôi có cần các chỉ mục riêng cho từng loại truy vấn không, hoặc một chỉ mục nhiều cột có hoạt động không?


22

Tôi phần nào biết câu trả lời cho câu hỏi này rồi, nhưng tôi luôn cảm thấy như thể có nhiều hơn tôi cần chọn về chủ đề này.

Hiểu biết cơ bản của tôi là nói chung, một chỉ mục duy nhất bao gồm tất cả các lĩnh vực bạn có thể truy vấn / sắp xếp tại bất kỳ thời điểm nào có thể không hữu ích, nhưng tôi đã thấy loại điều này. Như trong, có người nghĩ, "Chà, nếu chúng ta chỉ đưa tất cả những thứ này vào một chỉ mục, cơ sở dữ liệu có thể sử dụng nó để tìm những gì nó cần", mà không bao giờ thấy một kế hoạch thực hiện cho một số truy vấn thực tế đang được chạy.

Hãy tưởng tượng một bảng như vậy:

id int pk/uid
name varchar(50)
customerId int (foreign key)
dateCreated datetime

Tôi có thể thấy một chỉ số duy nhất bao gồm cả name, customerIddateCreatedcác lĩnh vực.

Nhưng sự hiểu biết của tôi là một chỉ mục như vậy sẽ không được sử dụng trong một truy vấn như, ví dụ:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

Đối với một truy vấn như vậy, đối với tôi, một ý tưởng tốt hơn sẽ là một chỉ mục bao gồm các trường customerIddateCreatedcác trường, với customerIdtrường là 'đầu tiên'. Điều này sẽ tạo ra một chỉ mục có dữ liệu được sắp xếp theo cách mà truy vấn này có thể nhanh chóng tìm thấy những gì nó cần - theo thứ tự mà nó cần.

Một điều khác tôi thấy, có lẽ thường xuyên như lần đầu tiên, là các chỉ mục riêng lẻ trên mỗi lĩnh vực; như vậy, một trong mỗi ngày name, customerIddateCreatedcác lĩnh vực.

Không giống như ví dụ đầu tiên, kiểu sắp xếp này đôi khi đối với tôi ít nhất là hữu ích một phần; kế hoạch thực hiện của truy vấn có thể cho thấy rằng ít nhất là nó sử dụng chỉ mục trên customerIdđể chọn các bản ghi, nhưng nó không sử dụng chỉ mục với dateCreatedtrường để sắp xếp chúng.


Tôi biết đây là một câu hỏi rộng, bởi vì câu trả lời cụ thể cho bất kỳ truy vấn cụ thể nào trên bất kỳ nhóm bảng cụ thể nào thường là để xem kế hoạch thực hiện nói rằng nó sẽ làm gì, và nếu không, hãy đưa các chi tiết cụ thể của bảng và truy vấn vào tài khoản. Ngoài ra, tôi biết rằng nó phụ thuộc vào tần suất truy vấn có thể được chạy trái ngược với chi phí duy trì một chỉ mục cụ thể cho nó.

Nhưng tôi cho rằng những gì tôi đang hỏi là 'điểm bắt đầu' chung cho các chỉ mục, ý tưởng về việc có các chỉ mục cụ thể cho các truy vấn cụ thể, thường xuyên được kéo và các trường trong mệnh đề WHERE hoặc ORDER BY có hợp lý không?

Câu trả lời:


27

Bạn đúng khi truy vấn ví dụ của bạn sẽ không sử dụng chỉ mục đó.

Trình hoạch định truy vấn sẽ xem xét sử dụng một chỉ mục nếu:

  • tất cả các trường có trong nó được tham chiếu trong truy vấn
  • một số lĩnh vực bắt đầu từ đầu được tham chiếu

Nó sẽ không thể sử dụng các chỉ mục bắt đầu bằng một trường không được truy vấn sử dụng.

Vì vậy, ví dụ của bạn:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

nó sẽ xem xét các chỉ số như:

[customerId]
[customerId], [dateCreated]
[customerId], [dateCreated], [name]

nhưng không:

[name], [customerId], [dateCreated]

Nếu nó tìm thấy cả hai [customerId][customerId], [dateCreated], [name]quyết định thích cái này hơn cái kia sẽ phụ thuộc vào số liệu thống kê chỉ số phụ thuộc vào ước tính cân bằng dữ liệu trong các trường. Nếu [customerId], [dateCreated]được xác định, nó sẽ thích hơn hai cái kia trừ khi bạn đưa ra gợi ý chỉ số cụ thể ngược lại.

Không có gì lạ khi thấy một chỉ mục được xác định cho mọi lĩnh vực theo kinh nghiệm của tôi, mặc dù điều này hiếm khi tối ưu vì quản lý bổ sung cần thiết để cập nhật các chỉ mục khi chèn / cập nhật và không gian thêm cần thiết để lưu trữ chúng, bị lãng phí khi một nửa chúng có thể không bao giờ được sử dụng - nhưng trừ khi DB của bạn thấy tải nặng, hiệu năng sẽ không bị hôi thối ngay cả với các chỉ số dư thừa.

Các chỉ mục cụ thể cho các truy vấn thường xuyên sẽ chậm do quét bảng hoặc chỉ mục nói chung là một ý tưởng tốt, mặc dù vậy, đừng lạm dụng nó vì bạn có thể trao đổi một vấn đề hiệu suất cho một vấn đề khác. [customerId], [dateCreated]Ví dụ: nếu bạn xác định là một chỉ mục, hãy nhớ rằng trình hoạch định truy vấn sẽ có thể sử dụng chỉ mục đó cho các truy vấn sẽ sử dụng một chỉ mục ngay [customerId]khi có mặt. Mặc dù chỉ sử dụng [customerId]sẽ hiệu quả hơn một chút so với sử dụng chỉ số ghép, nhưng điều này có thể được giảm thiểu bằng cách kết thúc việc có hai chỉ số cạnh tranh không gian trong RAM thay vì một (mặc dù toàn bộ bộ làm việc bình thường của bạn dễ dàng phù hợp với RAM, cuộc cạnh tranh bộ nhớ thêm này có thể không một vấn đề).


+1; thông tin tuyệt vời, đặc biệt là lời nhắc (mà tôi có xu hướng quên!) rằng trình lập kế hoạch có thể sử dụng một chỉ mục ghép vào những thời điểm khi nó chỉ cần (các) trường đầu tiên từ nó cho một truy vấn.
Andrew Barber

6

Để trả lời câu hỏi ban đầu của bạn, vâng, các chỉ mục phải được thiết kế xung quanh các truy vấn , không chỉ bảng . Thứ tự các lĩnh vực trong chỉ mục là cực kỳ quan trọng. Thiết kế một chỉ mục duy nhất để tối ưu cho nhiều truy vấn khó hơn và bạn sẽ phải đánh đổi.

Về điểm thứ hai của bạn, vâng, một loạt các chỉ mục trên các trường riêng lẻ là phổ biến khó chịu. Tôi thấy điều đó mọi lúc trong môi trường của tôi và thường là cờ đỏ cho tôi rằng nhóm phát triển đã không làm việc với một DBA để thiết kế các chỉ mục phù hợp.

Chiến lược của tôi để thiết kế các chỉ mục, là lập chỉ mục:

  • Các trường được sử dụng trong WHERE (theo thứ tự chọn lọc)
  • Các trường được sử dụng trong ĐẶT HÀNG B BYNG
  • Bao gồm các trường khác (nếu cần) để tạo chỉ mục bao phủ

Vì vậy, ví dụ của bạn:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

Tôi có thể sẽ thiết kế một chỉ mục trên (CustomerID, dateCreated) INCLUDE (id, name). Chỉ số bao phủ này có nghĩa là truy vấn không bao giờ phải truy cập vào bảng gốc, cải thiện hiệu năng rất nhiều.

Ví dụ này là quá đơn giản. Một chỉ mục ngây thơ trên chỉ (CustomerID) cũng sẽ hoạt động gần như (giả sử rằng mỗi khách hàng chỉ có một đại diện duy nhất, do đó chỉ cần một dấu trang tra cứu duy nhất vào bảng). Thậm chí có thể có ích khi thực hiện một chỉ mục được nhóm trên (ID khách hàng, ID), tùy thuộc vào những truy vấn khác chạy trên bảng.


+1 cho "các chỉ mục phải được thiết kế xung quanh các truy vấn, không chỉ bảng" và phần còn lại của câu trả lời, chẳng hạn như lưu ý rằng ví dụ này rất đơn giản.
Andrew Barber
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.