Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Phân mảnh chỉ mục được nhóm không mong muốn

Trong phần khởi đầu từ loạt bài về 'điều chỉnh hiệu suất giật đầu gối', tôi muốn thảo luận về cách phân mảnh chỉ mục có thể ảnh hưởng đến bạn trong một số trường hợp.

Phân mảnh chỉ mục là gì?

Hầu hết mọi người nghĩ về 'phân mảnh chỉ mục' có nghĩa là vấn đề trong đó các trang lá chỉ mục không theo thứ tự - trang lá chỉ mục với giá trị khóa tiếp theo không phải là trang tiếp giáp vật lý trong tệp dữ liệu với trang lá chỉ mục hiện đang được kiểm tra . Đây được gọi là phân mảnh logic (và một số người gọi nó là phân mảnh bên ngoài - một thuật ngữ khó hiểu mà tôi không thích).

Sự phân mảnh lôgic xảy ra khi một trang lá chỉ mục đã đầy và cần có khoảng trống trên đó, để chèn hoặc để tạo một bản ghi hiện có dài hơn (từ việc cập nhật một cột có độ dài thay đổi). Trong trường hợp đó, Storage Engine tạo một trang trống mới và di chuyển 50% số hàng (thường, nhưng không phải luôn luôn) từ trang đầy đủ sang trang mới. Thao tác này tạo khoảng trống trong cả hai trang, cho phép tiến hành chèn hoặc cập nhật và được gọi là tách trang. Có những trường hợp bệnh lý thú vị liên quan đến việc tách trang lặp lại từ một thao tác đơn lẻ và việc tách trang làm tăng cấp chỉ mục, nhưng chúng nằm ngoài phạm vi của bài đăng này.

Khi quá trình tách trang xảy ra, nó thường gây ra phân mảnh lôgic vì trang mới được phân bổ rất ít có khả năng tiếp giáp về mặt vật lý với trang đang được phân chia. Khi một chỉ mục có nhiều phân mảnh lôgic, quá trình quét chỉ mục bị chậm lại do không thể thực hiện quá trình đọc vật lý của các trang cần thiết một cách hiệu quả (sử dụng các lần đọc 'đầu đọc' nhiều trang) khi các trang lá không được lưu trữ theo thứ tự trong tệp dữ liệu .

Đó là định nghĩa cơ bản của phân mảnh chỉ mục, nhưng có một loại phân mảnh chỉ mục thứ hai mà hầu hết mọi người không xem xét:mật độ trang thấp (đôi khi gọi là phân mảnh nội bộ, một thuật ngữ khó hiểu mà tôi không thích).

Mật độ trang là thước đo lượng dữ liệu được lưu trữ trên một trang chỉ mục. Khi tách trang xảy ra với trường hợp 50/50 thông thường, mỗi trang lá (phần tách và trang mới) chỉ còn lại với mật độ trang 50%. Mật độ trang càng thấp, càng có nhiều không gian trống trong chỉ mục và do đó, càng nhiều dung lượng đĩa và bộ nhớ vùng đệm mà bạn có thể coi là bị lãng phí. Tôi đã viết blog về vấn đề này vài năm trước và bạn có thể đọc về vấn đề này ở đây.

Bây giờ tôi đã đưa ra định nghĩa cơ bản về hai loại phân mảnh chỉ mục, tôi sẽ gọi chung chúng là 'phân mảnh'.

Trong phần còn lại của bài đăng này, tôi muốn thảo luận về ba trường hợp mà các chỉ mục được nhóm có thể bị phân mảnh ngay cả khi bạn đang tránh các thao tác rõ ràng sẽ gây ra phân mảnh (tức là chèn ngẫu nhiên và cập nhật bản ghi dài hơn).

Phân mảnh từ Xóa

“Làm thế nào việc xóa khỏi trang lá chỉ mục được nhóm lại có thể gây ra hiện tượng tách trang?” bạn có thể hỏi. Nó sẽ không xảy ra, trong những trường hợp bình thường (và tôi đã ngồi suy nghĩ về nó trong vài phút để đảm bảo rằng không có trường hợp bệnh lý kỳ lạ nào đó! Nhưng hãy xem phần bên dưới…) Tuy nhiên, việc xóa có thể khiến mật độ trang ngày càng thấp hơn.

Hãy tưởng tượng trường hợp chỉ mục được phân nhóm có giá trị khóa nhận dạng bigint, vì vậy các phần chèn sẽ luôn ở phía bên phải của chỉ mục và sẽ không bao giờ được chèn vào phần trước đó của chỉ mục (cấm ai đó gửi lại giá trị nhận dạng - có khả năng rất có vấn đề!). Bây giờ, hãy tưởng tượng rằng khối lượng công việc sẽ xóa các bản ghi khỏi bảng mà không cần thiết nữa, sau đó tác vụ dọn dẹp bản sao nền sẽ lấy lại không gian trên trang và nó sẽ trở thành không gian trống.

Trong trường hợp không có bất kỳ chèn ngẫu nhiên nào (không thể xảy ra trong trường hợp của chúng tôi trừ khi ai đó gửi lại danh tính hoặc chỉ định giá trị khóa để sử dụng sau khi bật SET IDENTITY INSERT cho bảng), sẽ không có bản ghi mới nào sử dụng không gian đã được giải phóng khỏi các bản ghi đã xóa. Điều này có nghĩa là mật độ trang trung bình của các phần trước đó của chỉ mục nhóm sẽ giảm đều đặn, dẫn đến việc tăng dung lượng ổ đĩa bị lãng phí và bộ nhớ vùng đệm như tôi đã mô tả trước đó.

Việc xóa có thể gây ra phân mảnh, miễn là bạn coi mật độ trang là một phần của "phân mảnh".

Phân mảnh từ Cách ly Ảnh chụp nhanh

SQL Server 2005 đã giới thiệu hai mức cách ly mới:cách ly ảnh chụp nhanh và cách ly ảnh chụp nhanh đã cam kết đọc. Hai ngôn ngữ này có ngữ nghĩa hơi khác nhau, nhưng về cơ bản cho phép các truy vấn xem chế độ xem tại thời điểm của cơ sở dữ liệu và cho các lựa chọn không có khóa-va chạm. Đó là một sự đơn giản hóa lớn, nhưng nó đủ cho mục đích của tôi.

Để tạo điều kiện thuận lợi cho các mức cô lập này, nhóm phát triển tại Microsoft mà tôi lãnh đạo đã triển khai một cơ chế gọi là lập phiên bản. Cách hoạt động của việc lập phiên bản là bất cứ khi nào một bản ghi thay đổi, phiên bản thay đổi trước của bản ghi được sao chép vào kho lưu trữ phiên bản trong tempdb và bản ghi đã thay đổi sẽ được thêm một thẻ lập phiên bản 14 byte vào cuối nó. Thẻ chứa một con trỏ đến phiên bản trước của bản ghi, cùng với dấu thời gian có thể được sử dụng để xác định đâu là phiên bản chính xác của bản ghi cho một truy vấn cụ thể để đọc. Một lần nữa, được đơn giản hóa rất nhiều, nhưng đó chỉ là phần bổ sung 14 byte mà chúng tôi quan tâm.

Vì vậy, bất cứ khi nào bản ghi thay đổi khi một trong các mức cách ly này có hiệu lực, nó có thể mở rộng thêm 14 byte nếu chưa có thẻ lập phiên bản cho bản ghi. Điều gì sẽ xảy ra nếu không có đủ dung lượng cho 14 byte thừa trên trang lá chỉ mục? Đúng vậy, hiện tượng tách trang sẽ xảy ra, gây ra sự phân mảnh.

Bạn có thể nghĩ rằng vấn đề lớn là bản ghi vẫn đang thay đổi nên nếu nó vẫn thay đổi kích thước thì có thể xảy ra hiện tượng tách trang. Không - logic đó chỉ đúng nếu thay đổi bản ghi là để tăng kích thước của cột có độ dài thay đổi. Thẻ lập phiên bản sẽ được thêm ngay cả khi cột có độ dài cố định được cập nhật!

Đúng vậy - khi đang phát phiên bản, cập nhật cho các cột có độ dài cố định có thể khiến bản ghi mở rộng, có khả năng gây ra hiện tượng tách và phân mảnh trang. Điều thú vị hơn nữa là việc xóa cũng sẽ thêm thẻ 14 byte, vì vậy việc xóa trong một chỉ mục được phân nhóm có thể gây ra hiện tượng tách trang khi sử dụng phiên bản!

Điểm mấu chốt ở đây là việc bật một trong hai hình thức cô lập ảnh chụp nhanh có thể dẫn đến phân mảnh đột ngột bắt đầu xảy ra trong các chỉ mục được phân nhóm mà trước đây không có khả năng phân mảnh.

Phân mảnh từ các cuốn thứ hai có thể đọc được

Trường hợp cuối cùng tôi muốn thảo luận là sử dụng phụ lục có thể đọc được, một phần của tính năng nhóm khả dụng đã được thêm vào SQL Server 2012.

Khi bạn bật bản sao thứ cấp có thể đọc được, tất cả các truy vấn bạn thực hiện đối với bản sao thứ cấp sẽ được chuyển đổi sang sử dụng cách ly ảnh chụp nhanh bên dưới vỏ bọc. Điều này ngăn các truy vấn chặn việc phát lại liên tục các bản ghi nhật ký từ bản sao chính, vì mã khôi phục có được các khóa khi nó diễn ra.

Để làm điều này, cần có các thẻ lập phiên bản 14 byte trên các bản ghi trên bản sao thứ cấp. Có một vấn đề xảy ra, vì tất cả các bản sao cần phải giống hệt nhau để quá trình phát lại nhật ký hoạt động. Chà, không hoàn toàn. Nội dung thẻ lập phiên bản không liên quan vì chúng chỉ được sử dụng trên phiên bản đã tạo ra chúng. Nhưng bản sao thứ cấp không thể thêm thẻ lập phiên bản, làm cho bản ghi dài hơn, vì điều đó sẽ thay đổi bố cục vật lý của bản ghi trên một trang và phá vỡ việc phát lại bản ghi. Tuy nhiên, nếu các thẻ lập phiên bản đã ở đó, nó có thể sử dụng không gian mà không bị hỏng bất kỳ thứ gì.

Vì vậy, đó chính xác là những gì sẽ xảy ra. Công cụ lưu trữ đảm bảo rằng mọi thẻ lập phiên bản cần thiết cho bản sao phụ đều đã có sẵn, bằng cách thêm chúng vào bản sao chính!

Ngay sau khi bản sao thứ cấp có thể đọc được của cơ sở dữ liệu được tạo, bất kỳ cập nhật nào đối với bản ghi trong bản sao chính sẽ khiến bản ghi có thẻ 14 byte trống được thêm vào, để 14 byte được tính đúng trong tất cả các bản ghi nhật ký . Thẻ không được sử dụng cho bất kỳ việc gì (trừ khi tính năng cô lập ảnh chụp nhanh được bật trên chính bản sao chính), nhưng thực tế là thẻ được tạo khiến bản ghi mở rộng và nếu trang đã đầy thì…

Có, việc kích hoạt bản sao thứ cấp có thể đọc được sẽ gây ra tác động tương tự đối với bản sao chính giống như khi bạn bật tính năng cô lập ảnh chụp nhanh trên nó - phân mảnh.

Tóm tắt

Đừng nghĩ rằng vì bạn đang tránh sử dụng GUID làm khóa cụm và tránh cập nhật các cột có độ dài thay đổi trong bảng của mình thì các chỉ mục được nhóm của bạn sẽ không bị phân mảnh. Như tôi đã mô tả ở trên, có những yếu tố môi trường và khối lượng công việc khác có thể gây ra sự cố phân mảnh trong các chỉ mục nhóm của bạn mà bạn cần lưu ý.

Bây giờ, đừng vội vàng và nghĩ rằng bạn không nên xóa các bản ghi, không nên sử dụng cách ly ảnh chụp nhanh và không nên sử dụng các bản phụ có thể đọc được. Bạn chỉ cần lưu ý rằng tất cả chúng đều có thể gây ra sự phân mảnh và biết cách phát hiện, loại bỏ và giảm thiểu nó.

SQL Sentry có một công cụ thú vị, Fragmentation Manager, bạn có thể sử dụng công cụ này như một tiện ích bổ sung cho Performance Advisor để giúp tìm ra các vấn đề về phân mảnh và sau đó giải quyết chúng. Bạn có thể ngạc nhiên về sự phân mảnh mà bạn tìm thấy khi kiểm tra! Như một ví dụ nhanh, ở đây tôi có thể thấy trực quan - xuống cấp độ phân vùng riêng lẻ - có bao nhiêu phân mảnh tồn tại, tốc độ nó diễn ra theo cách đó, bất kỳ mẫu nào tồn tại và tác động thực sự của nó đối với bộ nhớ lãng phí trong hệ thống:

Dữ liệu SQL Sentry Fragmentation Manager (nhấp để phóng to)

Trong bài đăng tiếp theo của tôi, tôi sẽ thảo luận thêm về phân mảnh và cách giảm thiểu nó để làm cho nó ít có vấn đề hơn.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng cờ theo dõi 3226 để ngăn chặn ghi nhật ký sao lưu

  2. Thuộc tính ACID của Báo cáo &Giao dịch

  3. Nghệ thuật tổng hợp dữ liệu trong SQL từ các tổng hợp đơn giản đến trượt

  4. Mọi thứ bạn cần biết về toán tử LIKE trong SQL

  5. Các nguyên tắc cơ bản về biểu thức bảng, Phần 9 - Chế độ xem, so sánh với các bảng dẫn xuất và CTE