Có bao nhiêu chỉ mục cơ sở dữ liệu là quá nhiều?


109

Tôi đang làm việc trong một dự án với cơ sở dữ liệu Oracle khá lớn (mặc dù câu hỏi của tôi cũng áp dụng tốt cho các cơ sở dữ liệu khác). Chúng tôi có một giao diện web cho phép người dùng tìm kiếm trên hầu hết mọi tổ hợp trường có thể có.

Để làm cho những tìm kiếm này diễn ra nhanh chóng, chúng tôi đang thêm chỉ mục vào các trường và kết hợp các trường mà chúng tôi tin rằng người dùng sẽ thường tìm kiếm. Tuy nhiên, vì chúng tôi không thực sự biết khách hàng của mình sẽ sử dụng phần mềm này như thế nào, nên thật khó để biết nên tạo chỉ mục nào.

Không gian không phải là một mối quan tâm; chúng tôi có một ổ RAID 4 terabyte mà chúng tôi đang sử dụng chỉ một phần nhỏ. Tuy nhiên, tôi lo lắng về các hình phạt hiệu suất có thể xảy ra khi có quá nhiều chỉ số. Bởi vì những chỉ mục đó cần được cập nhật mỗi khi một hàng được thêm, xóa hoặc sửa đổi, tôi tưởng tượng sẽ là một ý tưởng tồi nếu có hàng chục chỉ mục trên một bảng.

Vậy bao nhiêu chỉ số được coi là quá nhiều? 10? 25? 50? Hay tôi chỉ nên đề cập đến những trường hợp thực sự, thực sự phổ biến và hiển nhiên và bỏ qua mọi thứ khác?

Câu trả lời:


87

Nó phụ thuộc vào các hoạt động xảy ra trên bảng.

Nếu có nhiều SELECT và rất ít thay đổi, hãy lập chỉ mục tất cả những gì bạn thích .... những điều này sẽ (có khả năng) tăng tốc các câu lệnh SELECT.

Nếu bảng bị ảnh hưởng nhiều bởi CẬP NHẬT, CHÈN + XÓA ... thì chúng sẽ rất chậm với rất nhiều chỉ mục vì tất cả chúng cần được sửa đổi mỗi khi một trong những hoạt động này diễn ra

Phải nói rằng, rõ ràng bạn có thể thêm rất nhiều chỉ mục vô nghĩa vào một bảng mà sẽ không làm được gì cả. Việc thêm các chỉ mục B-Tree vào một cột có 2 giá trị khác biệt sẽ là vô nghĩa vì nó không bổ sung bất cứ thứ gì về mặt tra cứu dữ liệu. Các giá trị trong cột càng độc đáo thì chỉ mục đó càng được hưởng lợi nhiều hơn.


1
Chỉ cần làm rõ, chỉ số trên 2 giá trị có thể không vô nghĩa trong trường hợp cụ thể, khi một giá trị hiếm khi xảy ra và bạn muốn tra cứu nó. Vì vậy, vấn đề không phải là về mức độ độc đáo của các giá trị, mà là về mức độ chọn lọc của chỉ mục.
charlie_pl

44

Tôi thường tiến hành như thế này.

  1. Nhận nhật ký của các truy vấn thực chạy trên dữ liệu vào một ngày bình thường.
  2. Thêm chỉ mục để các truy vấn quan trọng nhất đạt được các chỉ mục trong kế hoạch thực thi của chúng.
  3. Cố gắng tránh lập chỉ mục các trường có nhiều cập nhật hoặc chèn
  4. Sau một vài chỉ mục, hãy lấy một nhật ký mới và lặp lại.

Như với tất cả các tối ưu hóa, tôi dừng khi đạt đến hiệu suất được yêu cầu (điều này rõ ràng ngụ ý rằng điểm 0. sẽ nhận được các yêu cầu hiệu suất cụ thể).


26

Mọi người khác đã cho bạn lời khuyên tuyệt vời. Tôi có thêm một gợi ý cho bạn khi bạn tiến lên. Tại một số thời điểm, bạn phải đưa ra quyết định về chiến lược lập chỉ mục tốt nhất của mình. Tuy nhiên, cuối cùng, chiến lược lập chỉ mục CÓ KẾ HOẠCH tốt nhất vẫn có thể tạo ra các chỉ mục mà cuối cùng vẫn không được sử dụng. Một chiến lược cho phép bạn tìm các chỉ mục không được sử dụng là theo dõi việc sử dụng chỉ mục. Bạn thực hiện như sau: -

alter index my_index_name monitoring usage;

Sau đó, bạn có thể theo dõi liệu chỉ mục có được sử dụng hay không từ thời điểm đó trở đi bằng cách truy vấn v $ object_usage. Thông tin về điều này có thể tìm thấy trong Hướng dẫn dành cho Quản trị viên Cơ sở dữ liệu Oracle® .

Chỉ cần nhớ rằng nếu bạn có chiến lược nhập kho là giảm các chỉ mục trước khi cập nhật bảng, sau đó tạo lại chúng, bạn sẽ phải thiết lập chỉ mục để theo dõi lại và bạn sẽ mất mọi lịch sử theo dõi cho chỉ mục đó.


14

Trong kho dữ liệu, việc có số lượng chỉ mục cao là rất phổ biến. Tôi đã làm việc với các bảng dữ kiện có hai trăm cột và 190 trong số đó được lập chỉ mục.

Mặc dù có một chi phí cho điều này, nó phải được hiểu trong bối cảnh rằng trong kho dữ liệu, chúng tôi thường chỉ chèn một hàng một lần, chúng tôi không bao giờ cập nhật nó, nhưng sau đó nó có thể tham gia vào hàng nghìn truy vấn SELECT có thể được lợi từ việc lập chỉ mục trên bất kỳ Các cột.

Để có tính linh hoạt tối đa, kho dữ liệu thường sử dụng các chỉ mục bitmap cột đơn ngoại trừ các cột có số lượng cao, trong đó các chỉ mục btree (được nén) có thể được sử dụng.

Chi phí duy trì chỉ mục chủ yếu liên quan đến chi phí ghi vào rất nhiều khối và khối sẽ tách ra khi các hàng mới được thêm vào với các giá trị "ở giữa" các phạm vi giá trị hiện có cho cột đó. Điều này có thể được giảm thiểu bằng cách phân vùng và tải dữ liệu mới được căn chỉnh với sơ đồ phân vùng và bằng cách sử dụng chèn đường dẫn trực tiếp.

Để giải quyết câu hỏi của bạn một cách trực tiếp hơn, tôi nghĩ rằng có thể tốt để lập chỉ mục lúc đầu, nhưng đừng ngại thêm nhiều chỉ mục hơn nếu các truy vấn chống lại bảng có lợi.


Đó là nhiều trên một thực tế? Tôi đã đoán bạn sắp nói thứ nguyên. Đó là một usecase khá kỳ lạ. Nhưng, bạn rock với tư cách là một DBA nên tôi sẽ nói rằng, tôi rõ ràng là thiếu một cái gì đó.
Stephanie Trang

@Stephanie, chúng ta có rất nhiều tình huống giống nhau .. David đã đề cập đó là các chỉ mục bitmap. Chúng tôi cũng sử dụng các chỉ mục BITMAP JOIN. Có, trên thực tế. Oracle có thể thực hiện các hoạt động AND rất hiệu quả trên các chỉ mục bitmap. Ví dụ: bạn có thể có mệnh đề WHERE với 5 thuộc tính số lượng thấp, mỗi thuộc tính có một chỉ mục bitmap. Nếu bạn nhìn vào kế hoạch thực thi, nó sẽ có một bitmap VÀ các hoạt động (về cơ bản là một bitmap và hoạt động hiệu quả), sau đó xuống kế hoạch thực thi, bạn sẽ thấy chuyển đổi bitmap thành rowids. Nó thực sự nhanh chóng.
Tagar

12

Trong một cách diễn giải của Einstein về sự đơn giản, hãy thêm nhiều chỉ mục tùy thích và không thêm nữa.

Tuy nhiên, nghiêm túc mà nói, mọi chỉ mục bạn thêm đều yêu cầu bảo trì bất cứ khi nào dữ liệu được thêm vào bảng. Trên các bảng chủ yếu chỉ được đọc, nhiều chỉ mục là một điều tốt. Trên các bảng có tính năng động cao, càng ít càng tốt.

Lời khuyên của tôi là bao gồm các trường hợp phổ biến và hiển nhiên, sau đó, khi bạn gặp phải các vấn đề mà bạn cần tốc độ cao hơn trong việc lấy dữ liệu từ các bảng cụ thể, hãy đánh giá và thêm các chỉ số vào thời điểm đó.

Ngoài ra, bạn nên đánh giá lại kế hoạch lập chỉ mục của mình vài tháng một lần, chỉ để xem liệu có bất kỳ chỉ số mới nào cần lập chỉ mục hoặc bất kỳ chỉ số nào bạn đã tạo không được sử dụng cho bất kỳ thứ gì và cần được loại bỏ .


1
Tôi đồng ý về việc đánh giá lại. Quản trị tốt không bao giờ là một nhiệm vụ "đặt nó và quên nó". Thay đổi phần mềm. Yêu cầu thay đổi. Thay đổi cách sử dụng. Một chức năng mới, có vẻ tầm thường được giới thiệu vào một ngày nào đó có thể nhanh chóng trở thành nút thắt cổ chai lớn nhất của bạn và mã bánh mì nền tảng của ngày hôm qua có thể trở thành chất béo không hoạt động và không cần thiết chỉ xoay quanh việc tiêu thụ tài nguyên. Tôi cũng đồng ý với cách tiếp cận lặp đi lặp lại. Nếu bạn làm quá nhiều cùng một lúc, bạn sẽ không biết điều gì hiệu quả.
durette

6

Ngoài những điểm mà mọi người khác đã nêu ra, Trình tối ưu hóa dựa trên chi phí phải chịu chi phí khi tạo kế hoạch cho một câu lệnh SQL nếu có nhiều chỉ mục hơn vì có nhiều kết hợp hơn để nó xem xét. Bạn có thể giảm điều này bằng cách sử dụng chính xác các biến liên kết để các câu lệnh SQL ở trong bộ đệm SQL. Oracle sau đó có thể thực hiện phân tích cú pháp mềm và sử dụng lại kế hoạch mà nó đã tìm thấy lần trước.

Như mọi khi, không có gì là đơn giản. Nếu có các cột và biểu đồ bị lệch liên quan thì đây có thể là một ý tưởng tồi.

Trong các ứng dụng web của mình, chúng tôi có xu hướng giới hạn các kết hợp tìm kiếm mà chúng tôi cho phép. Nếu không, bạn sẽ phải kiểm tra mọi sự kết hợp theo nghĩa đen để đảm bảo rằng bạn không gặp phải vấn đề tiềm ẩn mà một ngày nào đó ai đó sẽ tìm ra. Chúng tôi cũng đã triển khai giới hạn tài nguyên để ngăn chặn điều này gây ra sự cố ở những nơi khác trong ứng dụng nếu xảy ra sự cố.


Tôi đã bình chọn nhưng ... Tôi sẽ nói rằng thời gian phân tích cú pháp thêm trong khi thú vị và học thuật, nó sẽ không bao giờ ảnh hưởng đến lựa chọn của tôi cho số chỉ mục chính xác. đồng ý?
Stephanie Trang

@StephaniePage Tôi chưa thực hiện một thử nghiệm để chứng minh bất cứ điều gì. Tuy nhiên, tôi đã thấy một dự án đã tạo một chỉ mục một cột trên mỗi cột một cách ngây thơ. Nếu một số bảng có 80 cột, tôi đoán nó có thể bắt đầu tạo ra tác động. Oracle dường như xem xét chi phí truy cập theo từng chỉ mục. Nhưng vâng, tôi đồng ý, có nhiều điều quan trọng hơn phải xem xét hơn điều này.
WW.

Mmm ... Tôi tin rằng có một khoảng thời gian tối đa mà Oracle sẽ dành cho một phân tích cú pháp cứng ... hãy xem xét một SQL có nhiều hơn một vài bảng, chẳng hạn như 7 hoặc 8, chỉ riêng lựa chọn thứ tự nối có thể tạo ra hàng trăm các đường dẫn truy cập.
Stephanie Trang

6

Tôi đã thực hiện một số thử nghiệm đơn giản trên dự án thực và cơ sở dữ liệu MySql thực của mình. Tôi đã trả lời trong chủ đề này: Chi phí lập chỉ mục nhiều cột db là bao nhiêu?

Nhưng tôi nghĩ sẽ tốt hơn nếu tôi trích dẫn nó ở đây:

Tôi đã thực hiện một số thử nghiệm đơn giản bằng cách sử dụng dự án thực của mình và cơ sở dữ liệu MySql thực.

Kết quả của tôi là: thêm chỉ mục trung bình (1-3 cột trong một chỉ mục) vào bảng - làm cho việc chèn chậm hơn 2,1%. Vì vậy, nếu bạn thêm 20 chỉ mục, lượt chèn của bạn sẽ chậm hơn 40-50%. Nhưng lựa chọn của bạn sẽ nhanh hơn 10-100 lần.

Vì vậy, nó là ok để thêm nhiều chỉ mục? - Tùy :) Tôi đã cho bạn kết quả của tôi - Bạn quyết định!


Đây không nên được coi là lời tiên tri nếu không có tất cả các chi tiết. Đặc biệt là vì bạn không thể nhân hiệu suất tăng / giảm từ hành động này sang hành động khác. Cơ sở vẫn như cũ: thêm nhiều chỉ mục hơn và các lần chèn của bạn cuối cùng sẽ chậm hơn vì tạo chỉ mục.
SovietFrontier

3

Cuối cùng bạn cần bao nhiêu chỉ mục phụ thuộc vào hoạt động của các ứng dụng chạy trên máy chủ cơ sở dữ liệu của bạn.

Nói chung, bạn càng chèn nhiều thì chỉ mục của bạn càng trở nên khó khăn hơn. Mỗi lần bạn thực hiện chèn, tất cả các chỉ mục bao gồm bảng đó phải được cập nhật.

Bây giờ nếu ứng dụng của bạn có một lượng đọc tốt hoặc thậm chí nhiều hơn nếu gần như là đọc tất cả, thì các chỉ mục là cách để thực hiện vì sẽ có những cải tiến hiệu suất lớn với chi phí rất thấp.


3

Không có câu trả lời tĩnh theo ý kiến ​​của tôi, loại điều này thuộc 'điều chỉnh hiệu suất'.

Có thể là mọi thứ mà ứng dụng của bạn thực hiện đều được tra cứu bằng khóa chính hoặc có thể là tùy chọn trong đó các truy vấn được thực hiện qua các tổ hợp trường không bị giới hạn và bất kỳ trường nào cụ thể đều có thể được sử dụng tại bất kỳ thời điểm nào.

Ngoài việc chỉ lập chỉ mục, còn có việc đăng ký lại DB của bạn để bao gồm các trường tìm kiếm được tính toán, bảng phân tách, v.v. - nó thực sự phụ thuộc vào hình dạng tải và thông số truy vấn của bạn, bao nhiêu / dữ liệu 'thực sự' cần được kết xuất lại bởi một truy vấn.

Nếu toàn bộ DB của bạn được bao phủ bởi các mặt tiền thủ tục được lưu trữ, thì việc biến trở nên dễ dàng hơn một chút, vì bạn không phải lo lắng về mọi truy vấn đặc biệt. Hoặc bạn có thể hiểu sâu về các loại truy vấn sẽ đánh vào DB của bạn và có thể giới hạn việc điều chỉnh đối với những truy vấn đó.

Đối với SQL Server, tôi thấy công cụ cố vấn Điều chỉnh Cơ sở dữ liệu hữu ích - bạn thiết lập khối lượng công việc 'điển hình' và nó có thể đưa ra các đề xuất về việc thêm / xóa chỉ mục và thống kê. Tôi chắc chắn rằng các DB khác có các công cụ tương tự, dù là 'chính thức' hoặc bên thứ ba.


3

Đây thực sự là một câu hỏi lý thuyết nhiều hơn thực tế. Chỉ số ảnh hưởng đến hiệu suất của bạn phụ thuộc vào phần cứng bạn có, phiên bản Oracle, các loại chỉ mục, v.v. Hôm qua, tôi đã nghe Oracle công bố một bộ lưu trữ chuyên dụng do HP sản xuất, được cho là hoạt động nhanh hơn 10 lần với cơ sở dữ liệu 11g. Đối với trường hợp của bạn, có thể có một số giải pháp: 1. Có một lượng lớn chỉ mục (> 20) và xây dựng lại chúng hàng ngày (hàng đêm). Điều này sẽ đặc biệt hữu ích nếu bảng nhận được hàng nghìn cập nhật / xóa hàng ngày. 2. Phân vùng bảng của bạn (nếu điều đó áp dụng mô hình dữ liệu của bạn). 3. Sử dụng một bảng riêng biệt cho dữ liệu mới / cập nhật và chạy quy trình hàng đêm kết hợp dữ liệu với nhau. Điều này sẽ yêu cầu một sự thay đổi trong logic ứng dụng của bạn. 4. Chuyển sang IOT (bảng tổ chức chỉ mục), nếu dữ liệu của bạn hỗ trợ điều này.

Tất nhiên có thể có nhiều giải pháp khác cho trường hợp như vậy. Đề xuất đầu tiên của tôi dành cho bạn, là sao chép DB sang môi trường phát triển và chạy một số thử nghiệm căng thẳng đối với nó.


Tôi không hiểu việc xây dựng lại các chỉ mục sẽ giúp ích như thế nào hoặc IOT sẽ giúp ích như thế nào.
David Aldridge

IOT - nếu có thể thiết kế lại ứng dụng để sử dụng kiểu dữ liệu do người dùng xác định mới, thì IOT sẽ tiết kiệm chi phí xung quanh việc lập chỉ mục bảng. đây có thể không phải là trường hợp ở đây. nó thực sự phụ thuộc. xây dựng lại chỉ mục - trong trường hợp có nhiều chỉ mục và dữ liệu mới không được lập chỉ mục.
Moshe

IOT vẫn là một cấu trúc chỉ mục, với chi phí cao hơn khi chia khối so với chỉ mục thông thường. "xây dựng lại chỉ mục - trong trường hợp có nhiều chỉ mục và dữ liệu mới không được lập chỉ mục" ... bạn đang nói về RDBMS nào không duy trì chỉ mục tự động cho các mục mới?
David Aldridge

David - tất nhiên là bạn đúng. Tôi đã trộn điều đó với khả năng của SQL Server chỉ lập chỉ mục Tìm kiếm toàn văn bản theo yêu cầu. Ước gì Oracle có nó, vì nó có thể hữu ích trong trường hợp này. Tôi khuyên bạn nên gắn bó với hai gợi ý còn lại.
Moshe 27-08

2

Nếu bạn chủ yếu đọc (và ít cập nhật) thì thực sự không có lý do gì để không lập chỉ mục mọi thứ bạn cần lập chỉ mục. Nếu bạn cập nhật thường xuyên, thì bạn có thể cần phải thận trọng về số lượng chỉ mục của bạn. Không có con số khó, nhưng bạn sẽ nhận thấy khi mọi thứ bắt đầu chậm lại. Đảm bảo rằng chỉ mục được phân nhóm của bạn là chỉ mục có ý nghĩa nhất dựa trên dữ liệu.


2

Một điều bạn có thể xem xét là xây dựng các chỉ mục để nhắm mục tiêu một tổ hợp tìm kiếm tiêu chuẩn. Nếu cột1 thường được tìm kiếm và cột2 thường được sử dụng với nó và cột3 đôi khi được sử dụng với cột2 và cột1, thì chỉ mục trên cột1, cột2 và cột3 theo thứ tự đó có thể được sử dụng cho bất kỳ trường hợp nào trong ba trường hợp đó, mặc dù chỉ một chỉ số phải được duy trì.


2

Chỉ mục áp dụng chi phí khi bảng cơ sở được cập nhật. Một chỉ mục cung cấp một lợi ích khi nó được sử dụng để sắp xếp một truy vấn. Đối với mỗi chỉ số, bạn cần cân đối giữa chi phí và lợi ích. Truy vấn chạy chậm hơn bao nhiêu nếu không có chỉ mục? Lợi ích của việc chạy nhanh hơn là bao nhiêu? Bạn hoặc người dùng của bạn có thể chịu được tốc độ chậm khi thiếu chỉ mục không?

Bạn có thể chịu đựng thêm thời gian cần thiết để hoàn thành cập nhật không?

Bạn cần so sánh chi phí và lợi ích. Đó là đặc biệt cho tình huống của bạn. Không có số lượng chỉ mục kỳ diệu nào vượt qua ngưỡng "quá nhiều".

Ngoài ra còn có chi phí của không gian cần thiết để lưu chỉ mục, nhưng bạn đã nói rằng trong tình huống của bạn đó không phải là vấn đề. Điều này cũng đúng trong hầu hết các trường hợp, với điều kiện dung lượng ổ đĩa rẻ như thế nào.


1

Có bao nhiêu cột? Tôi luôn được yêu cầu tạo chỉ mục một cột, không phải nhiều cột. Vì vậy, không có nhiều chỉ mục hơn số lượng cột, IMHO.


1

Điều thực sự xảy ra là đừng thêm chỉ mục trừ khi bạn biết (và điều này thường có nghĩa là thu thập số liệu thống kê sử dụng) rằng nó sẽ được sử dụng thường xuyên hơn nhiều so với khi được cập nhật.

Bất kỳ chỉ mục nào không đáp ứng tiêu chí đó sẽ khiến bạn tốn nhiều chi phí để xây dựng lại hơn là hình phạt về hiệu suất của việc không có nó trong trường hợp kỳ lạ mà nó đã được sử dụng.


1

Máy chủ Sql cung cấp cho bạn một số công cụ tốt cho phép bạn xem chỉ mục nào đang thực sự được sử dụng. Bài viết này, http://www.mssqltips.com/tip.asp?tip=1239 , cung cấp cho bạn một số truy vấn để bạn có cái nhìn sâu sắc hơn về mức độ sử dụng của một chỉ mục, thay vì mức độ cập nhật của chỉ mục.


0

Nó hoàn toàn dựa trên các cột đang được sử dụng trong mệnh đề Where. Và với tư cách là Quy tắc Ngón tay cái, chúng ta phải có các chỉ mục trên các Cột Khoá Ngoại để tránh bị CHẾT. Báo cáo AWR nên phân tích định kỳ để hiểu nhu cầu của các chỉ mục.


2
Chỉ mục trên cột khóa ngoại để tránh bế tắc? Bạn có tài liệu tham khảo giải thích tại sao và làm thế nào đây là trường hợp?
Jay Sullivan
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.