Thực hành tốt nhất để làm theo với các chỉ mục cơ sở dữ liệu [đóng]


17

Một số DO và DONT để cải thiện hiệu suất cơ sở dữ liệu bằng cách sử dụng chỉ mục là gì?

DO sẽ là một trường hợp trong đó một chỉ mục sẽ được tạo hoặc một mẹo liên quan đến chỉ mục khác sẽ cải thiện hiệu suất.

Một KHÔNG sẽ là một trường hợp khi một chỉ mục không nên được tạo ra, hoặc một hành động liên quan đến chỉ mục khác có thể làm tổn hại đến hiệu suất.


3
hồ sơ, hồ sơ, hồ sơ
GrandmasterB

Câu trả lời:


15

Điều này phụ thuộc một phần vào cơ sở dữ liệu được sử dụng để làm gì, vì trong các chỉ mục chung làm chậm việc chèn và cập nhật và tăng tốc truy vấn. Trong kho dữ liệu, thường không có cập nhật và chèn theo đợt, giúp tạo chỉ mục dễ dàng hơn, và rất nhiều truy vấn, được tăng tốc với nhiều chỉ mục. Trong cơ sở dữ liệu trực tuyến để bán hàng trên web và tương tự, có rất nhiều phần chèn và cập nhật, do đó, việc có nhiều hơn một vài chỉ mục được chọn cẩn thận sẽ làm chậm nó.

Nếu bạn nhận được nhiều truy vấn thuộc một loại cụ thể, bạn có thể tạo một chỉ mục cho truy vấn, mặc dù đó là nhiều hơn cho xử lý trực tuyến hơn là kho dữ liệu. Nếu các cột nhất định xuất hiện rất nhiều trong các truy vấn, bạn có thể muốn có một chỉ mục trên cột đó và điều này đặc biệt hữu ích cho các kho dữ liệu, được truy vấn theo nhiều cách khác nhau và thường không thể đoán trước.

Bất cứ khi nào bạn thêm hoặc xóa chỉ mục, hãy thử làm một bài kiểm tra hiệu suất để xem nó có tác dụng gì. Không có điều đó, bạn đang bị mù.

Có những cuốn sách về điều chỉnh truy vấn và cơ sở dữ liệu, thường dành riêng cho một hệ thống cơ sở dữ liệu và sử dụng các công cụ của RDBMS đó. Tuy nhiên, nếu bạn thấy mình cần tối ưu hóa cơ sở dữ liệu nhiều, bạn đang chạy một hoạt động lớn và có lẽ nên thuê một DBA có chuyên môn phù hợp.


17

Nó rất phụ thuộc vào cách bạn sử dụng bảng của bạn. Không có câu trả lời duy nhất và đơn giản.

Lời khuyên tốt nhất tôi có thể cung cấp cho bạn là: sử dụng một cố vấn điều chỉnh . Họ sẽ phân tích các lệnh cơ sở dữ liệu trong khi bạn đang sử dụng ứng dụng, sau đó họ sẽ thực hiện các bài kiểm tra tải đối với nó để cung cấp cho bạn những lời khuyên có ý nghĩa.

Chúng tồn tại cho SQL Server & Oracle . Tôi không biết nếu các DBMS khác có chúng, chỉ là tôi nghi ngờ họ không cung cấp các công cụ cơ bản như vậy.

Vài đề xuất ngẫu nhiên:

  • Các chỉ mục cung cấp mức tăng hiệu suất cao khi được áp dụng trên các cột thường được bao gồm trong mệnh đề WHERE
  • Sử dụng chỉ mục Clustered cho cột được sử dụng nhiều nhất trong các truy vấn của bạn.
  • Đừng quên rằng bạn có thể tạo nhiều chỉ mục với sự kết hợp của các cột (vì chúng được sử dụng trong các truy vấn của bạn)
  • Có nhiều chỉ mục sẽ làm giảm hiệu suất của các lệnh INSERT.

Lời khuyên cuối cùng : nếu các buổi biểu diễn DB thực sự quan trọng đối với dự án của bạn, hãy thuê một chuyên gia. Đó là những gì tôi đã làm.


2
+1 cho các chỉ mục trên các tổ hợp cột. Chỉ số trên các cột abkhông giống như một chỉ mục trên (a, b). Cái sau gần như tốt như chỉ số ađể tăng tốc truy vấn với một điều kiện trên a, tốt hơn nhiều cho các truy vấn có điều kiện trên abkhông hữu ích cho các truy vấn bmột mình. (Hầu hết các cơ sở dữ liệu sẽ không sử dụng nó. Oracle sẽ, nhưng không lấy được số dặm mà nó thường làm.)
btilly

2
+1, sẽ thêm "tìm hiểu kế hoạch truy vấn để bạn biết lập chỉ mục nào"
Steven A. Lowe

4

@Pierre 303 đã nói rồi, nhưng tôi sẽ nói lại. NÊN sử dụng các chỉ mục trên các tổ hợp cột. Một chỉ mục kết hợp trên (a, b)chỉ chậm hơn một chút cho các truy vấn trên amột chỉ mục trên amột mình và tốt hơn nhiều nếu truy vấn của bạn kết hợp cả hai cột. Một số cơ sở dữ liệu có thể tham gia các chỉ mục trên abtrước khi nhấn bảng, nhưng điều này gần như không tốt bằng việc có một chỉ mục kết hợp. Khi bạn tạo một chỉ mục kết hợp, bạn nên đặt cột có khả năng được tìm kiếm đầu tiên trong chỉ mục kết hợp.

Nếu cơ sở dữ liệu của bạn hỗ trợ nó, DO đưa chỉ số về chức năng mà xuất hiện trong các truy vấn chứ không phải cột. (Nếu bạn đang gọi một hàm trên một cột, các chỉ mục trên cột đó là vô ích.)

Nếu bạn đang sử dụng một cơ sở dữ liệu với các bảng tạm thời đúng là bạn có thể tạo và tiêu diệt một cách nhanh chóng (ví dụ như PostgreSQL, MySQL, nhưng không Oracle), sau đó DO tạo chỉ số trên bảng tạm thời.

Nếu bạn đang sử dụng một cơ sở dữ liệu cho phép nó (ví dụ Oracle), DO khóa trong kế hoạch truy vấn tốt. Tối ưu hóa truy vấn theo thời gian sẽ thay đổi kế hoạch truy vấn. Họ thường cải thiện kế hoạch. Nhưng đôi khi họ làm cho nó tồi tệ hơn đáng kể. Nói chung, bạn sẽ không thực sự nhận thấy các cải tiến kế hoạch - truy vấn không phải là nút cổ chai. Nhưng một kế hoạch xấu duy nhất có thể phá hủy một trang web bận rộn.

KHÔNG có chỉ mục trên các bảng bạn sắp thực hiện tải dữ liệu lớn. Việc thả chỉ mục, tải dữ liệu, sau đó xây dựng lại chỉ mục sẽ nhanh hơn nhiều so với việc duy trì chúng khi bạn tải bảng.

KHÔNG sử dụng các chỉ mục trên các truy vấn phải truy cập nhiều hơn một phần nhỏ của một bảng lớn. . Sẽ không hữu ích khi lập chỉ mục về giới vì bạn vẫn phải truy cập 50% số hàng. Bạn thực sự muốn sử dụng quét toàn bộ bảng thay thế. Lý do là các chỉ mục kết thúc việc truy cập một tệp lớn một cách ngẫu nhiên, khiến bạn cần tìm kiếm đĩa. Tìm kiếm đĩa là chậm. Như một trường hợp, gần đây tôi đã quản lý để tăng tốc truy vấn dài một giờ giống như:

SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
  JOIN big_table
    ON big_table.small_table_id = small_table.id
GROUP BY small_table.id

dưới 3 phút bằng cách viết lại như sau:

SELECT small_table.id, big_table_summary.summed_value
FROM small_table
  JOIN (
      SELECT small_table_id, SUM(some_value) as summed_value
      FROM big_table
      GROUP BY small_table_id
    ) big_table_summary
    ON big_table_summary.small_table_id =  small_table.id

đã buộc cơ sở dữ liệu phải hiểu rằng nó không nên cố gắng sử dụng chỉ mục hấp dẫn trên big_table.small_table_id. (Một cơ sở dữ liệu tốt, chẳng hạn như Oracle, nên tự mình tìm ra. Truy vấn này đang chạy trên MySQL.)

Cập nhật: Dưới đây là một lời giải thích về điểm tìm kiếm đĩa mà tôi đã thực hiện. Một chỉ mục cung cấp một tra cứu nhanh để cho biết vị trí của dữ liệu trong bảng. Đây thường là một chiến thắng vì bạn sẽ chỉ nhìn vào dữ liệu bạn cần xem. Nhưng không phải lúc nào cũng vậy, đặc biệt nếu cuối cùng bạn sẽ xem xét rất nhiều dữ liệu. Đĩa truyền dữ liệu tốt, nhưng làm cho tra cứu chậm. Việc tra cứu ngẫu nhiên dữ liệu trên đĩa mất 1/200 giây. Phiên bản chậm của truy vấn đã làm một cái gì đó giống như 600.000 trong số đó và mất gần một giờ. (Nó đã tìm kiếm nhiều hơn thế, nhưng bộ nhớ đệm đã bắt được một số trong số đó.) Ngược lại, phiên bản nhanh biết rằng nó phải đọc mọi thứ và truyền dữ liệu với tốc độ 70 MB / giây. Nó đã vượt qua một bảng 11 GB trong vòng dưới 3 phút.


Xin chào, tôi bối rối trước ví dụ của bạn. Tôi đã nghĩ rằng việc sử dụng chỉ mục sẽ giúp mọi thứ nhanh hơn, đó không phải là điểm của chỉ mục? Bạn có nói rằng nếu một truy vấn sẽ truy cập> 5% của một bảng, thì việc có một chỉ mục trên cột bạn đang tìm kiếm sẽ khiến mọi thứ chậm hơn?
Nhấp vào Upvote

@Click Upvote: Nếu một truy vấn truy cập hơn 5% (phần chính xác phụ thuộc nhiều vào phần cứng và dữ liệu) của một bảng, thì sẽ không nhanh hơn khi không sử dụng chỉ mục cho truy vấn đó. Có một chỉ mục không gây hại miễn là bạn không sử dụng nó. Tôi sẽ cập nhật với nhiều chi tiết hơn về lý do tại sao.
btilly

Thông tin hữu ích. Thêm vào đó, ví dụ như mysqlperformanceblog.com 2007/08/28 / Nhưng tôi đã tự hỏi, có phải 'bỏ qua khóa' không theo cách này mà bạn cần phải biến nó thành một truy vấn phụ?
Inca

@Inca: Tôi không biết về 'bỏ qua khóa'. Tôi chuyển đổi cơ sở dữ liệu đủ để thường có những thứ cụ thể về cơ sở dữ liệu mà tôi không biết. Từ âm thanh của nó sẽ hoạt động, nhưng hiệu quả thấp hơn đáng kể so với giải pháp cuối cùng của tôi. Sự khác biệt là sẽ tham gia, sau đó nhóm, trong khi nhóm của tôi, sau đó tham gia. Điều này tiết kiệm công việc khi tham gia vì cần ít hồ sơ hơn để tham gia.
btilly

"Cơ sở dữ liệu tốt (ví dụ: Oracle, nhưng không phải MySQL)": vui lòng tránh các công cụ quảng cáo ngu ngốc như vậy, đặc biệt là khi bạn bỏ qua thực tế rằng MySQL hoàn toàn có thể sử dụng nhiều chỉ mục cùng một lúc (lưu ý "INDEX MERGE" trong các kế hoạch truy vấn) .
Patrick Allaert

2

NÊN: Lập chỉ mục cho rất ít trường mà bạn truy cập nhiều nhất thông qua truy vấn và / hoặc so sánh.

KHÔNG: Lập chỉ mục mọi lĩnh vực trong bảng nghĩ rằng nó sẽ làm cho nó nhanh hơn.

Tôi không có bất kỳ số liệu thống kê nào về nó, nhưng tôi cố gắng giữ không quá 4 trường được lập chỉ mục trong một bảng nếu tôi có thể giúp nó. Bình thường hóa cơ sở dữ liệu của tôi thường giúp giảm các số này vì mọi thứ đều có thể tìm kiếm được bằng phím số (dù sao cũng nhanh hơn). Tôi cố gắng tránh xa các trường văn bản đầy đủ để lập chỉ mục. Chúng khá nặng.


2

Về cơ bản, các chỉ số tăng tốc tìm kiếm nhưng làm chậm việc viết và chúng chiếm dung lượng. Đó là sự đánh đổi đang được thực hiện.

Bất kỳ lĩnh vực nào thường được sử dụng để tham gia, tìm kiếm / so sánh hoặc đặt hàng theo là một ứng cử viên cho một chỉ mục. Để biết nó thực sự có lợi, đo lường. Tuy nhiên, các khóa ngoại của các bảng được nối nhiều với nhiều bản ghi (> 1000) và một vài phần chèn sẽ trả hết.

Đối với các trường văn bản, bạn có thể lập chỉ mục trên một phần của trường (ví dụ: 6 ký tự đầu tiên) sẽ tăng tốc truy vấn của bạn nhưng làm giảm tải trên các chỉ mục. Tìm kiếm toàn văn bản (tìm kiếm trên like %substring%) yêu cầu các kỹ thuật khác nhau, mà tôi không quen thuộc, vì vậy tôi không thể cho bạn lời khuyên ở đó.

Một tình huống quan trọng trong đó các chỉ số sẽ không giúp ích: bạn không thể sử dụng chỉ mục của các trường ngày hoặc ngày hoàn chỉnh khi bạn tìm kiếm (/ tham gia / đặt hàng) vào một phần của ngày. Một chỉ mục trên date_createdsẽ không giúp bạn với một truy vấn như select * from t where year(date_created) = 2011. Trong mysql bạn không thể tạo một chỉ mục vào một phần của ngày. (Khi bạn sử dụng ' between' thay vì year()nó có thể sử dụng chỉ mục trên trường ngày.)

Thông tin thêm về MYSQL trong hướng dẫn sử dụng: http://dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html


1

NÊN: Cố gắng giữ tổng kích thước của chỉ mục được nhóm ở mức tối thiểu. Các mục chỉ mục được nhóm sẽ được bao gồm trong các chỉ mục không được nhóm khác và từ đây có khả năng lãng phí không gian đĩa.


1

Hãy nghĩ về một bảng như một từ vựng, trong đó các bài viết được sắp xếp theo thứ tự xuất hiện (hoặc không có thứ tự hữu ích nào cả) và về một chỉ mục bảng như một chỉ mục sách cho từ vựng đó.

Bạn sử dụng một chỉ mục để nhanh chóng tìm thấy một cái gì đó trong một cuốn sách. Thay vì quét toàn bộ cuốn sách, bạn chỉ cần tìm khóa trong chỉ mục (một chỉ mục thường được sắp xếp theo cách nào đó (theo danh mục, theo lĩnh vực khoa học, theo thời đại lịch sử, v.v.), điều này cũng có nghĩa là bạn sẽ không phải quét toàn bộ chỉ mục) và sau đó nhảy đến trang bên phải.

Tuy nhiên, không giống như một cuốn sách, một bảng không được in một lần và sau đó không thay đổi. Nó được cập nhật mọi lúc, và do đó mọi chỉ số phải được cập nhật với nó. Điều này tất nhiên đi kèm với chi phí không gian và thời gian, điều đó chỉ có thể được chứng minh bằng tính hữu ích của một chỉ mục.

Vì vậy, hãy sử dụng một chỉ mục cho một cột, nếu cột đó được sử dụng làm khóa trong các truy vấn tìm kiếm thường xuyên và không sử dụng một chỉ mục, nếu không. Từ thường xuyên là một định lượng tốt như nó được, khi nói chung. Cuối cùng, bạn sẽ phải ước tính tốt những cái nào là thường xuyên, sau đó chỉ cần hiệu suất điểm chuẩn có hoặc không có chỉ số trong trường hợp có nghi ngờ.

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.