Những cột nào thường tạo ra các chỉ mục tốt?


98

Trong phần tiếp theo "Chỉ mục là gì và tôi có thể sử dụng chúng như thế nào để tối ưu hóa các truy vấn trong cơ sở dữ liệu của mình? ", Nơi tôi đang cố gắng tìm hiểu về chỉ mục, cột nào là ứng cử viên chỉ mục tốt? Cụ thể cho một cơ sở dữ liệu MS SQL?

Sau một số googling, mọi thứ tôi đã đọc cho thấy rằng các cột nói chung đang tăng và duy nhất tạo ra một chỉ mục tốt (những thứ như auto_increment của MySQL), tôi hiểu điều này, nhưng tôi đang sử dụng MS SQL và tôi đang sử dụng GUID cho các khóa chính, vì vậy có vẻ như rằng các chỉ mục sẽ không có lợi cho các cột GUID ...


Còn về "sách dạy nấu ăn" thì sao: mysql.rjweb.org/doc.php/index_cookbook_mysql
Rick James

Câu trả lời:


110

Các chỉ mục có thể đóng một vai trò quan trọng trong việc tối ưu hóa truy vấn và tìm kiếm kết quả một cách nhanh chóng từ các bảng. Vì vậy, bước quan trọng nhất là chọn cột được lập chỉ mục. Có hai vị trí chính mà chúng ta có thể xem xét lập chỉ mục: các cột được tham chiếu trong mệnh đề WHERE và các cột được sử dụng trong mệnh đề JOIN. Tóm lại, các cột như vậy phải được lập chỉ mục dựa vào đó bạn được yêu cầu để tìm kiếm các bản ghi cụ thể. Giả sử, chúng ta có một bảng có tên người mua trong đó truy vấn SELECT sử dụng các chỉ mục như bên dưới:

SELECT
 buyer_id /* no need to index */
FROM buyers
WHERE first_name='Tariq' /* consider to use index */
AND last_name='Iqbal'   /* consider to use index */

Vì "buy_id" được tham chiếu trong phần SELECT, MySQL sẽ không sử dụng nó để giới hạn các hàng đã chọn. Do đó, không cần thiết phải lập chỉ mục nó. Dưới đây là một ví dụ khác đôi chút với ví dụ trên:

SELECT
 buyers.buyer_id, /* no need to index */
 country.name    /* no need to index */
FROM buyers LEFT JOIN country
ON buyers.country_id=country.country_id /* consider to use index */
WHERE
 first_name='Tariq' /* consider to use index */
AND
 last_name='Iqbal' /* consider to use index */

Theo các truy vấn trên first_name, các cột last_name có thể được lập chỉ mục khi chúng nằm trong mệnh đề WHERE. Ngoài ra, một trường bổ sung, country_id từ bảng country, có thể được xem xét để lập chỉ mục vì nó nằm trong mệnh đề JOIN. Vì vậy, lập chỉ mục có thể được xem xét trên mọi trường trong mệnh đề WHERE hoặc mệnh đề JOIN.

Danh sách sau đây cũng cung cấp một số mẹo mà bạn nên ghi nhớ khi có ý định tạo chỉ mục trong bảng của mình:

  • Chỉ lập chỉ mục những cột được yêu cầu trong mệnh đề WHERE và ORDER BY. Việc lập chỉ mục các cột quá nhiều sẽ dẫn đến một số bất lợi.
  • Cố gắng tận dụng tính năng "tiền tố chỉ mục" hoặc "chỉ mục nhiều cột" của MySQL. Nếu bạn tạo một chỉ mục chẳng hạn như INDEX (first_name, last_name), đừng tạo INDEX (first_name). Tuy nhiên, "tiền tố chỉ mục" hoặc "chỉ mục nhiều cột" không được khuyến nghị trong tất cả các trường hợp tìm kiếm.
  • Sử dụng thuộc tính NOT NULL cho các cột mà bạn coi là lập chỉ mục, để các giá trị NULL sẽ không bao giờ được lưu trữ.
  • Sử dụng tùy chọn --log-long-format để ghi lại các truy vấn không sử dụng chỉ mục. Bằng cách này, bạn có thể kiểm tra tệp nhật ký này và điều chỉnh các truy vấn của mình cho phù hợp.
  • Câu lệnh EXPLAIN giúp bạn tiết lộ rằng MySQL sẽ thực thi một truy vấn như thế nào. Nó chỉ ra cách thức và thứ tự các bảng được nối với nhau. Điều này có thể hữu ích nhiều cho việc xác định cách viết các truy vấn được tối ưu hóa và liệu các cột có cần được lập chỉ mục hay không.

Cập nhật (23/02/15):

Bất kỳ chỉ mục nào (tốt / xấu) đều làm tăng thời gian chèn và cập nhật.

Tùy thuộc vào chỉ mục của bạn (số chỉ mục và loại), kết quả được tìm kiếm. Nếu thời gian tìm kiếm của bạn sẽ tăng lên vì chỉ mục thì đó là chỉ mục xấu.

Có thể trong bất kỳ cuốn sách nào, "Trang chỉ mục" có thể có trang bắt đầu chương, số trang chủ đề bắt đầu, cũng bắt đầu trang chủ đề phụ. Một số giải thích rõ ràng trong trang Chỉ mục sẽ hữu ích nhưng chỉ mục chi tiết hơn có thể làm bạn bối rối hoặc sợ hãi. Các chỉ mục cũng đang có bộ nhớ.

Lựa chọn chỉ mục nên khôn ngoan. Hãy nhớ rằng không phải tất cả các cột đều yêu cầu chỉ mục.


Cảm ơn Somnath, Vì vậy, nó ngụ ý chỉ số chỉ nên được tạo ra cho các cột nơi chúng tôi đang lên kế hoạch để sử dụng WHERE, JOINShoặc HAVING?
Muhammad Babar

3
Có, sử dụng chỉ mục cho các cột mà bạn định sử dụng WHERE, JOINS hoặc HAVING. Nhưng cũng nên nhớ rằng, tất cả các cột điều kiện không yêu cầu chỉ mục. Đôi khi trong đó cột điều kiện chỉ được sử dụng một lần nên nó có thể không cần chỉ mục trong khi cột điều kiện khác được sử dụng trong nhiều truy vấn, vì vậy, bạn thích lập chỉ mục hơn cho cột đó.
Somnath Muluk

1
Câu trả lời sẽ có lợi khi đặt "các cột được tham chiếu trong mệnh đề WHERE và các cột được sử dụng trong mệnh đề JOIN" trong phần TL; DR.
jpmc 26

Vì vậy, bạn đang nói rằng nếu trong WHEREmệnh đề của tôi, tôi đang kiểm tra giá trị của một trường mà cột của nó chỉ có thể nhận hai giá trị, thì tôi nên lập chỉ mục cột nhị phân đó? Điều này có vẻ sai.
AjaxLeung

@AjaxLeung: Hãy nhớ câu châm ngôn của Knuth "Tối ưu hóa sớm là gốc rễ của mọi điều ác.". Bạn có thể tạo chỉ mục trên các cột nhị phân, nhưng nó phải phụ thuộc vào chi phí nào (như chèn, thời gian cập nhật). Nếu logic kinh doanh của bạn thường phụ thuộc vào công tắc nhị phân đó thì cột nhị phân có thể được yêu cầu phải có chỉ mục.
Somnath Muluk,

20

Một số người đã trả lời một câu hỏi tương tự ở đây: Làm thế nào để bạn biết chỉ số tốt là gì?

Về cơ bản, nó thực sự phụ thuộc vào cách bạn sẽ truy vấn dữ liệu của mình. Bạn muốn một chỉ mục nhanh chóng xác định một tập con nhỏ của tập dữ liệu của bạn có liên quan đến một truy vấn. Nếu bạn không bao giờ truy vấn bằng dấu dữ liệu, bạn không cần chỉ mục trên đó, ngay cả khi nó chủ yếu là duy nhất. Nếu tất cả những gì bạn làm là nhận các sự kiện đã xảy ra trong một phạm vi ngày nhất định, bạn chắc chắn muốn có một sự kiện. Trong hầu hết các trường hợp, một chỉ số về giới tính là vô nghĩa - nhưng nếu tất cả những gì bạn làm là nhận được số liệu thống kê về tất cả nam giới và riêng biệt, về tất cả nữ giới, thì bạn có thể rất đáng để tạo một chỉ số. Tìm ra các mẫu truy vấn của bạn sẽ là gì và truy cập vào tham số nào thu hẹp không gian tìm kiếm nhiều nhất và đó là chỉ mục tốt nhất của bạn.

Cũng nên xem xét loại chỉ mục bạn tạo - B-tree tốt cho hầu hết mọi thứ và cho phép truy vấn phạm vi, nhưng chỉ mục băm giúp bạn đi thẳng vào vấn đề (nhưng không cho phép phạm vi). Các loại chỉ mục khác có những ưu và nhược điểm khác.

Chúc may mắn!


9

Tất cả phụ thuộc vào những truy vấn bạn muốn hỏi về các bảng. Nếu bạn yêu cầu tất cả các hàng có giá trị nhất định cho cột X, bạn sẽ phải quét toàn bộ bảng nếu không thể sử dụng chỉ mục.

Chỉ mục sẽ hữu ích nếu:

  • Cột hoặc các cột có mức độ độc đáo cao
  • Bạn thường xuyên cần tìm kiếm một giá trị hoặc phạm vi giá trị nhất định cho cột.

Chúng sẽ không hữu ích nếu:

  • Bạn đang chọn một% lớn (> 10-20%) các hàng trong bảng
  • Việc sử dụng không gian bổ sung là một vấn đề
  • Bạn muốn tối đa hóa hiệu suất chèn. Mọi chỉ mục trên bảng đều làm giảm hiệu suất chèn và cập nhật vì chúng phải được cập nhật mỗi khi dữ liệu thay đổi.

Các cột khóa chính thường tuyệt vời để lập chỉ mục vì chúng là duy nhất và thường được sử dụng để tra cứu các hàng.


tìm kiếm chuỗi trong đó giá trị có thể ở bất kỳ đâu bên trong chuỗi có thể khiến nó không sử dụng các chỉ mục đó trong trường hợp đó.
Arthur Thomas 20-08

5

Nói chung (tôi không dùng mssql nên không thể nhận xét cụ thể), khóa chính tạo chỉ mục tốt. Chúng là duy nhất và phải có một giá trị được chỉ định. (Ngoài ra, các khóa chính tạo chỉ mục tốt đến mức chúng thường có chỉ mục được tạo tự động.)

Chỉ mục thực sự là một bản sao của cột đã được sắp xếp để cho phép tìm kiếm nhị phân (nhanh hơn nhiều so với tìm kiếm tuyến tính). Các hệ thống cơ sở dữ liệu có thể sử dụng nhiều thủ thuật khác nhau để tăng tốc độ tìm kiếm hơn nữa, đặc biệt nếu dữ liệu phức tạp hơn một số đơn giản.

Đề xuất của tôi là không sử dụng bất kỳ chỉ mục nào ban đầu và lập hồ sơ các truy vấn của bạn. Nếu một truy vấn cụ thể (chẳng hạn như tìm kiếm người theo họ chẳng hạn) được chạy rất thường xuyên, hãy thử tạo lại một chỉ mục trên các thuộc tính và cấu hình giảm hạng. Nếu có sự tăng tốc đáng kể đối với các truy vấn và tốc độ chèn và cập nhật chậm không đáng kể, hãy giữ chỉ mục.

(Xin lỗi nếu tôi đang lặp lại những thứ được đề cập trong câu hỏi khác của bạn, tôi đã không gặp nó trước đây.)


5

Bất kỳ cột nào sẽ được sử dụng thường xuyên để trích xuất dữ liệu từ bảng nên được lập chỉ mục.

Điều này bao gồm: khóa ngoại -

select * from tblOrder where status_id=:v_outstanding

trường mô tả -

select * from tblCust where Surname like "O'Brian%"

Các cột không cần phải là duy nhất. Trên thực tế, bạn có thể nhận được hiệu suất thực sự tốt từ chỉ mục nhị phân khi tìm kiếm các ngoại lệ.

select * from tblOrder where paidYN='N'

Đề cập rõ ràng của bạn về các khóa ngoại thực sự đã làm sáng tỏ mọi thứ đối với tôi khi xem xét việc tham gia.
pfabri

3

Nó thực sự phụ thuộc vào truy vấn của bạn. Ví dụ, nếu bạn hầu như chỉ ghi vào một bảng thì tốt nhất là không nên có bất kỳ chỉ mục nào, chúng chỉ làm chậm quá trình ghi và không bao giờ được sử dụng. Bất kỳ cột nào bạn đang sử dụng để nối với một bảng khác đều là một ứng cử viên sáng giá cho một chỉ mục.

Ngoài ra, hãy đọc về tính năng Thiếu chỉ mục. Nó giám sát các truy vấn thực tế đang được sử dụng đối với cơ sở dữ liệu của bạn và có thể cho bạn biết những chỉ mục nào sẽ cải thiện hiệu suất.


3

Cột GUID không phải là ứng cử viên tốt nhất để lập chỉ mục. Chỉ mục phù hợp nhất với các cột có kiểu dữ liệu có thể có một số thứ tự có ý nghĩa, tức là được sắp xếp (số nguyên, ngày, v.v.).

Không quan trọng nếu dữ liệu trong một cột nói chung đang tăng lên. Nếu bạn tạo một chỉ mục trên cột, chỉ mục sẽ tạo cấu trúc dữ liệu riêng của nó, sẽ chỉ đơn giản là tham chiếu đến các mục thực tế trong bảng của bạn mà không cần quan tâm đến thứ tự được lưu trữ (một chỉ mục không phân cụm). Sau đó, ví dụ: một tìm kiếm nhị phân có thể được thực hiện trên cấu trúc dữ liệu chỉ mục của bạn để cung cấp khả năng truy xuất nhanh chóng.

Cũng có thể tạo một "chỉ mục được phân cụm" để sắp xếp lại dữ liệu của bạn một cách vật lý. Tuy nhiên, bạn chỉ có thể có một trong những chỉ mục này cho mỗi bảng, trong khi bạn có thể có nhiều chỉ mục không phân cụm.


Chà, theo cách đó không hoàn toàn chính xác. Bạn có thể dễ dàng tạo chỉ mục thông thường, không phân cụm trên cột GUID - tại sao không? GUID có một nhược điểm lớn nếu bạn sử dụng nó làm khóa phân cụm (ví dụ: đối với CHỈ SỐ ĐƯỢC ĐIỀU CHỈNH) - thì việc sử dụng nó sẽ là một điều tồi tệ.
marc_s

1

Quy tắc ngón tay cái là các cột được sử dụng rất nhiều trong mệnh đề WHERE, ORDER BY, GROUP BY hoặc bất kỳ mệnh đề nào dường như được sử dụng thường xuyên trong các phép nối. Hãy nhớ rằng tôi đang đề cập đến các chỉ mục, KHÔNG phải Khóa chính

Không phải để đưa ra câu trả lời 'vani-ish', nhưng nó thực sự phụ thuộc vào cách bạn đang truy cập dữ liệu


1

Khóa chính của bạn phải luôn là một chỉ mục. (Tôi sẽ ngạc nhiên nếu nó không được MS SQL tự động lập chỉ mục, trên thực tế.) Bạn cũng nên thường xuyên lập chỉ mục các cột mà bạn SELECThoặc ORDERtheo; mục đích của chúng là vừa tra cứu nhanh một giá trị vừa là sắp xếp nhanh hơn.

Mối nguy hiểm thực sự duy nhất trong việc lập chỉ mục toonhiều cột là làm chậm các thay đổi đối với các hàng trong bảng lớn, vì tất cả các chỉ mục cũng cần cập nhật. Nếu bạn thực sự không chắc chắn nên lập chỉ mục những gì, chỉ cần xem xét các truy vấn chậm nhất của bạn, xem những cột nào đang được sử dụng thường xuyên nhất và lập chỉ mục chúng. Sau đó, xem chúng nhanh hơn bao nhiêu.


1

Các kiểu dữ liệu số được sắp xếp theo thứ tự tăng dần hoặc giảm dần là các chỉ mục tốt vì nhiều lý do. Đầu tiên, các con số thường được đánh giá nhanh hơn các chuỗi (varchar, char, nvarchar, v.v.). Thứ hai, nếu các giá trị của bạn không được sắp xếp theo thứ tự, các hàng và / hoặc trang có thể cần được xáo trộn để cập nhật chỉ mục của bạn. Đó là chi phí bổ sung.

Nếu bạn đang sử dụng SQL Server 2005 và sử dụng mã số duy nhất (guids) và KHÔNG cần chúng có tính chất ngẫu nhiên, hãy kiểm tra loại mã số duy nhất tuần tự.

Cuối cùng, nếu bạn đang nói về các chỉ mục nhóm, bạn đang nói về loại dữ liệu vật lý. Nếu bạn có một chuỗi làm chỉ mục nhóm của mình, điều đó có thể trở nên tồi tệ.


0

Nó sẽ nhanh hơn nếu bạn đang sử dụng GUID. Giả sử bạn có hồ sơ

  1. 100
  2. 200
  3. 3000
  4. ....

Nếu bạn có một chỉ mục (tìm kiếm nhị phân, bạn có thể tìm thấy vị trí thực của bản ghi mà bạn đang tìm kiếm trong thời gian O (lg n), thay vì tìm kiếm tuần tự theo thời gian O (n). Điều này là do bạn không biết mình có bản ghi nào trong bảng bạn.


0

Chỉ mục tốt nhất phụ thuộc vào nội dung của bảng và những gì bạn đang cố gắng hoàn thành.

Lấy ví dụ Một cơ sở dữ liệu thành viên với Khóa chính của Thành viên An sinh xã hội. Chúng tôi chọn SS bởi vì ứng dụng tham chiếu đến từng cá nhân theo cách này nhưng bạn cũng muốn tạo một chức năng tìm kiếm sẽ sử dụng họ và tên của các thành viên. Sau đó, tôi sẽ đề xuất tạo một chỉ mục trên hai trường đó.

Trước tiên, bạn nên tìm ra dữ liệu bạn sẽ truy vấn và sau đó xác định dữ liệu nào bạn cần được lập chỉ mục.

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.