Hiệu quả của việc thay thế các chỉ mục bằng các chỉ mục được lọc (giá trị không null) là gì?


10

Dự án của chúng tôi chạy một cơ sở dữ liệu rất lớn, rất phức tạp. Vì vậy, khoảng một tháng trước, chúng tôi nhận thấy rằng không gian được sử dụng bởi các cột được lập chỉ mục chứa các giá trị null đang trở nên quá lớn. Để đáp lại điều đó, tôi đã viết dưới dạng tập lệnh sẽ tự động tìm kiếm thông qua tất cả các chỉ mục cột đơn có chứa hơn 1% giá trị null, sau đó thả và tạo lại các chỉ mục đó dưới dạng các chỉ mục được lọc với điều kiện giá trị đó không phải là NULL. Điều này sẽ loại bỏ và tạo lại hàng trăm chỉ mục trong toàn bộ cơ sở dữ liệu và thường giải phóng gần 15% dung lượng được sử dụng bởi toàn bộ DB.

Bây giờ tôi có hai câu hỏi về điều này:

A) Nhược điểm của việc sử dụng các chỉ mục được lọc theo cách này là gì? Tôi cho rằng nó sẽ chỉ cải thiện hiệu suất, nhưng có bất kỳ rủi ro hiệu suất nào liên quan không?

B) Chúng tôi đã nhận được lỗi ( 'không thể bỏ chỉ mục XYZ vì nó không tồn tại hoặc bạn không có quyền' ) khi thả và tạo lại các chỉ mục, mặc dù khi được kiểm tra sau đó, mọi thứ đã diễn ra đúng như mong đợi. Làm thế nào điều này có thể xảy ra?

Cảm ơn vì bất kì sự giúp đỡ!

Chỉnh sửa: Đáp lại @Thomas Kejser

Xin chào và cảm ơn, nhưng hóa ra đây là một thảm họa. Vào thời điểm đó, chúng tôi không hiểu một số điều như:

  1. Trong một truy vấn, SQLOS tạo các kế hoạch chỉ mục trước khi xác định rằng nó không thể sử dụng các giá trị NULL để nối các cột của bảng. IE, bạn thực sự cần phải có bộ lọc mệnh đề WHERE phù hợp với chỉ mục cho từng và mọi chỉ mục được lọc được sử dụng trong truy vấn, hoặc chỉ mục sẽ hoàn toàn không được sử dụng.
  2. Bỏ và tạo các chỉ mục và cập nhật dự phòng thống kê của họ một lần nữa sau đó vẫn có thể không đủ để tạo ra các kế hoạch cập nhật, mà chúng tôi cho rằng họ sẽ làm. Nó xuất hiện trong một số trường hợp chỉ một khối lượng công việc đủ cao sẽ buộc SQL Server phải đánh giá lại các kế hoạch.
  3. Có một số biểu hiện cho chức năng của trình hoạch định thực thi rất khó xác định chỉ bằng ý thức và logic thông thường. Với hàng ngàn biến thể được mã hóa phía sau của các truy vấn khác nhau, các chỉ mục dường như vô dụng có thể giúp ích trong một số thống kê và kế hoạch truy vấn cuối cùng được sử dụng trong các truy vấn quan trọng.

Cuối cùng, những thay đổi này đã được hoàn nguyên. Vì vậy, các chỉ mục được lọc là một công cụ mạnh mẽ, nhưng bạn cần thực sự hiểu chính xác dữ liệu nào đang được tìm nạp từ các cột đó. Khi các chỉ mục bình thường ngoài các vấn đề không gian khá dễ áp ​​dụng, các chỉ mục được lọc đại diện cho các giải pháp rất tùy chỉnh. Chúng chắc chắn không phải là sự thay thế cho một chỉ mục thông thường, thay vào đó là một phần mở rộng cho chúng trong những trường hợp đặc biệt mà chúng được yêu cầu.


Bạn có thể muốn kiểm tra lại chiến lược lập chỉ mục của bạn quá. Nếu bạn có hàng trăm chỉ mục trường đơn thì có lẽ không tối ưu.
JNK

Sự cần thiết này xuất phát từ thực tế là cơ sở dữ liệu được kế thừa một phần từ hệ thống khác. Theo mặc định, chúng tôi có một số bảng trừu tượng và một số cột trừu tượng có thể hoàn toàn không được sử dụng, điều này tạo ra hầu hết số lượng lớn các giá trị NULL được lập chỉ mục này. Đối với các chỉ mục trường đơn, chúng được tạo từ yêu cầu cơ bản rằng mỗi khóa ngoại phải được lập chỉ mục và nhiều trong số đó nằm trong các cột này chứa hầu hết hoặc chỉ các giá trị NULL.
Kahn

Câu trả lời:


8

Cách tiếp cận rất thú vị. Upvote của tôi cho sự sáng tạo.

Vì bạn đã lấy lại không gian, tôi giả sử các chỉ mục ban đầu không còn đúng chỗ? Nhược điểm của các chỉ mục được lọc sau đó là:

  • Quá nhiều trong số chúng có thể khiến không gian tìm kiếm của trình tối ưu hóa tăng quá lớn, dẫn đến các kế hoạch truy vấn kém khi trình tối ưu hóa hết thời gian
  • Có một số tình huống trong đó một chỉ mục được lọc thậm chí sẽ không được xem xét, mặc dù tương đương không được lọc sẽ là. Đáng chú ý, điều này có thể xảy ra khi bạn nhận được một phép nối băm trên cột được lập chỉ mục hoặc nếu bạn cố gắng ĐẶT HÀNG THEO cột (không có bộ lọc)
  • Tham số truy vấn không hoạt động với các chỉ mục được lọc (xem: http://www.sqlservercentral.com/bloss/praticssqldba/2013/04/08/sql-server-part-9-filtered-index-a-new-way- cho hiệu suất-ngẫu hứng / )

Trong điều kiện thực tế, điều này có nghĩa là bạn phải cực kỳ cẩn thận với các chỉ mục được lọc vì chúng sẽ thường dẫn đến các kế hoạch truy vấn khủng khiếp. Tôi sẽ không đi xa đến mức gọi chúng là vô dụng, nhưng tôi xem chúng như một sự bổ sung cho các chỉ mục truyền thống, chứ không phải là một sự thay thế (như bạn đang cố gắng làm).


"Tham số truy vấn không hoạt động với các chỉ mục được lọc". điều này có thể được sửa với tùy chọn (biên dịch lại)
MichaelD

2

Thomas Kejser trả lời tốt chủ đề này ở trên.

Tôi chỉ nghĩ về việc thêm 2 xu.

Tôi đã thấy một số chỉ mục được lọc chỉ được sử dụng (được hiển thị trong kế hoạch thực hiện) khi bạn khớp chính xác mệnh đề where trong truy vấn của bạn là vị trí trong chỉ mục được lọc.

Bạn đã thử sử dụng các khung nhìn được lập chỉ mục ? cột thưa thớt ?

Tôi tin rằng khi bạn chỉ có các khớp bên trong, bạn có thể tạo chế độ xem được lập chỉ mục có chứa mệnh đề where của các chỉ mục được lọc của bạn và sau đó bạn có thể sử dụng chế độ xem thay thế.

Có thể có nhiều hơn một lượt xem. Nhưng giống như với các chỉ mục không được nhóm, quá nhiều sẽ làm chậm việc viết của bạn.

Theo kinh nghiệm của tôi, bạn sẽ có được những thành tựu tốt trong việc đọc nhưng bạn sẽ phải theo dõi việc ghi (chèn và cập nhật) đặc biệt nếu các bảng có liên quan đến sao chép.

Tuy nhiên, vì tôi hiểu mối quan tâm chính của bạn là the null valuesdo đó tôi sẽ đề xuất cho bạn các cột SPARSE trong các chỉ mục của bạn .

Các cột thưa thớt đặc biệt thích hợp cho các chỉ mục được lọc

Như tôi đã quảng cáo các cột thưa thớt, tôi sẽ không cảm thấy tốt nếu tôi không nói với bạn về những hạn chế của nó:

Khi thiết kế các bảng có các cột thưa thớt, hãy nhớ rằng cần thêm 2 byte phí cho mỗi cột thưa không có giá trị trong bảng khi một hàng đang được cập nhật.

Như là kết quả của việc này

yêu cầu bộ nhớ bổ sung, các bản cập nhật có thể bị lỗi bất ngờ với lỗi 576 khi tổng kích thước hàng, bao gồm cả chi phí bộ nhớ này, vượt quá 8019,

và không có cột nào có thể được đẩy ra khỏi hàng.

Hãy xem xét ví dụ> của một bảng có 600 cột kiểu thưa.

Nếu có 571 cột không null, thì tổng kích thước trên đĩa là 571 * 12 = 6852 byte. Sau khi bao gồm cả chi phí hàng bổ sung và tiêu đề cột thưa thớt, điều này tăng lên khoảng 6895 byte. Trang vẫn còn khoảng 1124 byte có sẵn trên đĩa. Điều này có thể mang lại ấn tượng rằng các cột bổ sung có thể được cập nhật thành công. Tuy nhiên, trong quá trình cập nhật, có thêm chi phí trong bộ nhớ là 2 * (số cột thưa thớt không null). Trong ví dụ này, bao gồm cả chi phí bổ sung - 2 * 571 = 1142 byte - tăng kích thước hàng trên đĩa lên khoảng 8037 byte. Kích thước này vượt quá kích thước tối đa được phép là 8019 byte. Vì tất cả các cột là loại dữ liệu có độ dài cố định, chúng không thể bị đẩy ra khỏi hàng. Kết quả là bản cập nhật thất bại với lỗi 576.

biết thêm chi tiết về liên kết ở trên, tuy nhiên tôi cũng thích đăng ở đây cảnh báo này:

Thay đổi một cột từ thưa thớt sang không đặc biệt hoặc không đặc biệt thành thưa thớt đòi hỏi phải thay đổi định dạng lưu trữ của cột.

Công cụ cơ sở dữ liệu SQL Server sử dụng quy trình sau để thực hiện thay đổi này:

1 - Thêm một cột mới vào bảng theo kích thước và định dạng lưu trữ mới.

2 - Đối với mỗi hàng trong bảng, cập nhật và sao chép giá trị được lưu trong cột cũ sang cột mới.

3 - Loại bỏ cột cũ khỏi lược đồ bảng.

4 - Xây dựng lại bảng (nếu không có chỉ mục được nhóm) hoặc xây dựng lại chỉ mục được nhóm để lấy lại không gian được sử dụng bởi cột cũ.


1
Chào. Hơi muộn một chút nhưng có, trong khi chúng tôi đã từ bỏ cách tiếp cận được mô tả trong chủ đề này từ lâu, gần đây chúng tôi đã quay lại với nó bằng một cách tiếp cận có chọn lọc hơn. Về cơ bản, chúng tôi đã xem xét việc sử dụng thống kê và mô hình kinh doanh để xác nhận các chỉ mục trên một bảng trên cơ sở bảng. Sau đó, kiểm tra nó bằng cách thêm một chỉ mục được lọc mới ở bên cạnh chỉ số bình thường và kiểm tra xem trong vài tuần cuối cùng cái nào được sử dụng. Sau khi xác nhận rằng CHỈ các chỉ mục được lọc đã được sử dụng trong các gói mới, chúng tôi đã loại bỏ các chỉ mục không được lọc thông thường.
Kahn

1
Ngoài ra, chúng tôi đã thay đổi khá nhiều cột thành các loại thưa thớt. Tuy nhiên, vấn đề với điều đó là như bạn sẽ thấy từ MSDN, việc thay đổi một loại cột thành thưa thớt về cơ bản buộc toàn bộ chỉ mục cụm được tạo lại. Làm điều này khá nặng cho các bảng lớn, phức tạp. Vì vậy, chúng tôi đã đổi tên các ràng buộc và bảng, tạo ra một ràng buộc mới với cùng một mô hình và tên gốc nhưng với các cột thưa thớt, sau đó chuyển dữ liệu vào bảng mới theo các lô thích hợp. Sau đó, một khi đã kiểm tra rằng mọi thứ đều ổn và tất cả các chỉ mục và FK đã được đặt lại, bỏ các bảng cũ.
Kahn

1
Ngoài ra, trong một số trường hợp sử dụng nén trang là tốt hơn nhiều, vì vậy cuối cùng chúng tôi đã làm điều đó. Nó cũng tiện vì bạn chỉ cần tạo chỉ mục được nhóm hiện có với DROP_EXISTING = ON, để làm cho nó đi xa, nhanh hơn nhiều so với đi tuyến đường thưa thớt. Đặc biệt là vì nó tránh được toàn bộ rắc rối của việc quản lý lại các chỉ mục và FK.
Kahn
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.