Xây dựng lại chỉ số khóa chính rất lớn


13

Tôi có một cơ sở dữ liệu SQL được lưu trữ trên Azure. Vấn đề là kích thước đang vượt khỏi tầm kiểm soát, tôi có thể thấy sự phân mảnh tới 99% trong các chỉ mục được phân cụm Chính.

Tôi có thể xây dựng lại tất cả các chỉ mục khác với online=ontùy chọn và nó sẽ không ảnh hưởng đến hiệu suất. Kích thước của một trong các chỉ số PK Clustered lớn hơn 200GB và đối với điều này, điều này REBUILD...WITH (ONLINE=ON)gây ra khóa.

Chúng tôi có người dùng từ tất cả các múi giờ truy cập trang web vì vậy thực sự, tôi không thể tìm thấy thời gian để tôi có thể xây dựng lại chỉ mục ngoại tuyến.

Chiến lược tốt nhất để xây dựng lại các chỉ số lớn mà không có thời gian chết trong trang web là gì?

Tôi tin rằng tổ chức lại sẽ không giúp đỡ vì sự phân mảnh là 99%. Vấn đề là bảng bị khóa ngay cả khi trực tuyến. Vấn đề chính là chỉ số lớn hơn 200GB. Khóa chính là một số nguyên.


4
@Techy, ngay cả với độ phân mảnh cao, REORGANIZEsẽ làm giảm phân mảnh trang lá và không gian nhỏ gọn như thế REBUILD, chỉ kém hiệu quả. Bạn có chắc chắn kích thước lớn là do sự phân mảnh? Các yếu tố điền là gì?
Dan Guzman

Bạn có biết những gì gây ra sự phân mảnh? Bao lâu sau khi xây dựng lại, bạn sẽ trở lại tại quảng trường 1? Bạn có thể đăng thêm thông tin về bảng của bạn?
bình tĩnh

2
@Techy Tôi đã chỉnh sửa câu hỏi để thêm một số thông tin bổ sung dựa trên nhận xét của bạn. Sẽ rất hữu ích nếu bạn cũng bao gồm định nghĩa bảng trong câu hỏi và các chi tiết bổ sung liên quan đến "bảng bị khóa ngay cả khi [xây dựng lại] trực tuyến." Những loại chờ đợi bạn đang nhìn thấy?
AMtwo

Câu trả lời:


9

Mặc dù đã muộn một chút, tôi sẽ đưa ra câu trả lời với hy vọng rằng nó sẽ giúp hoặc ít nhất là từ chối một số ý tưởng / bình luận bổ sung về vấn đề này bởi vì tôi nghĩ đó là một câu hỏi hay.

Đầu tiên, và tôi không biết liệu bạn có làm điều này hay không, nhưng xin đừng cho rằng mức độ phân mảnh cao trên chỉ mục sẽ luôn gây ra hiệu suất kém. Số liệu thống kê cũ (ví dụ: sys.dm_db_stats_properies ) và số lượng khoảng trắng lớn trên mỗi trang (ví dụ: cột avg_page_space_use_in_percent trong sys.dm_db_index_physical_stats dmv ) Có, các chỉ mục bị phân mảnh cao sẽ tạo ra nhiều số lần đọc hơn và bạn thường thấy các số liệu thống kê cũ và mức độ trắng cao hơn trên mỗi trang cùng với phân mảnh, nhưng phân mảnh không được liên kết trực tiếp với tối ưu hóa kế hoạch truy vấn cũng như tải bộ nhớ từ chỉ mục từ bao nhiêu sẽ thực sự tiêu thụ. Các gói truy vấn bị ảnh hưởng bởi số liệu thống kêdấu chân bộ nhớ của bạn có nhiều khoảng trắng hơn . Chẳng hạn, một chỉ số bị phân mảnh 99% nhưng có ít hơn 5% avg. khoảng trắng và thống kê cập nhật có thể không gây ra cho bạn các vấn đề hiệu năng nghiêm trọng so với kế hoạch thực hiện tồi do thống kê cũ hoặc phân trang liên tục của một chỉ số quá lớn để phù hợp hoàn toàn trong bộ nhớ vì có một lượng đáng kể không gian màu trắng hiện trên mỗi trang.

Nếu sự phân mảnh thực sự là một vấn đề , bạn có thể giảm nó, TRỰC TUYẾN, bằng cách đưa ra một ALTER INDEX ... REORGANIZEtuyên bố như được xác định bởi Dan Guzman trong các bình luận. Điều này sẽ không tạo ra một chỉ mục hợp lý như một REBUILDhoạt động, nhưng nó sẽ làm giảm sự phân mảnh của bạn. Chìa khóa ở đây là xác định các cửa sổ sử dụng thấp hơn trên cơ sở dữ liệu của bạn và chạy nó sau đó. Điều này có thể là 15 phút hoặc nhiều giờ, rõ ràng là càng lâu thì càng tốt, nhưng mấu chốt ở đây là thao tác này không quay trở lại và giữ lại bất kỳ tiến trình nào được thực hiện ngay cả khi bạn giết nó khi thực hiện giữa chừng.

Nếu, trong một thế giới hoàn hảo, nơi sự phân mảnh của bạn bị loại bỏ, nó sẽ có ý nghĩa hơn khi sử dụng phân vùng trên bảng này? Cơ sở dữ liệu Azure SQL cho phép phân vùng bảng và Microsoft có một bài viết tuyệt vời phác thảo một số chiến lược phân vùng cho Cơ sở dữ liệu Azure SQL . Nếu dữ liệu của bạn không dễ bay hơi, việc phân vùng nó có thể giúp giảm nhu cầu bảo trì và nếu được kết hợp với Nén bảng , bạn thậm chí có thể giảm cả dung lượng lưu trữ tổng thể của mình. Câu trả lời trước đây của Alberto Murillo ám chỉ việc sử dụng Phân vùng ngang dựa trên một vùng dữ liệu và phương pháp này có thể giúp tạo ra một số cửa sổ bảo trì cho bạn vì dữ liệu của bạn sẽ cụ thể hơn theo vùng thay vì toàn cầu.

Việc chuyển sang một bảng được phân đoạn sẽ không dễ dàng với sự vắng mặt của các cửa sổ bảo trì hiện tại của bạn, nhưng bạn có thể sử dụng một cách tiếp cận được nêu ra bởi Maria Zakourdaev , sử dụng Chế độ xem được phân vùng trên đầu bảng hiện tại của bạn và một bảng được phân vùng mới để bắt đầu phân vùng dữ liệu trong tương lai. Khi thời gian trôi qua (và hy vọng dữ liệu cũ của bạn bị xóa), cuối cùng bạn có thể chuyển hoàn toàn sang bảng được phân đoạn. Một lần nữa, tôi không biết dữ liệu hoặc ứng dụng của bạn, nhưng có lẽ cách tiếp cận này là thứ bạn có thể sử dụng.


4

Đầu tiên, điều quan trọng là xem xét liệu phân mảnh có vấn đề.

Nếu truy vấn của bạn chỉ thực hiện tìm kiếm một hàng, bạn có thể không nhận thấy sự phân mảnh nào cả. Trên các SAN hiện đại, bộ nhớ đệm cấp SAN có thể tạo ra các IO thực vật đủ nhanh để phân mảnh không thành vấn đề. Trên SSD, mẫu IO ngẫu nhiên do quét chỉ mục bị phân mảnh thực sự có thể mang lại hiệu suất tốt hơn so với dữ liệu không bị phân mảnh.

Thông thường, mọi người nhận thấy rằng việc xây dựng lại một chỉ mục đã khắc phục vấn đề về hiệu năng. Xây dựng lại một chỉ số cũng xây dựng số liệu thống kê mới. Nó có thể là trường hợp sửa chữa thực sự là số liệu thống kê mới, không xây dựng lại chỉ mục. UPDATE STATISTICS...WITH FULLSCANcó thể là một cách rẻ hơn, nhanh hơn, ít xâm phạm hơn để giải quyết vấn đề hiệu suất tương tự.

Nếu bạn không gặp vấn đề do phân mảnh, thì bạn có thể dành thời gian và công sức đáng kể để không có lợi ích thực sự.

Thứ hai, có hai loại phân mảnh:

  1. Sự phân mảnh vật lý. Đây là những gì hầu hết mọi người nghĩ về khi họ nghĩ về sự phân mảnh. Các trang bị lỗi, và cần phải được sắp xếp lại. Khi quét một chỉ mục, loại phân mảnh này đôi khi có thể là một vấn đề. Tôi thường nhận thấy điều này có tác động lớn nhất đến hiệu suất với các lần đọc vật lý . Nếu bạn đang xem kết quả từ sys.dm_db_index_physical_stats, con số này là avg_fragmentation_in_percentcột.

  2. Phân mảnh mật độ thấp. Sự phân mảnh này được gây ra bởi các trang chỉ chứa một phần dữ liệu. Bạn có mật độ dữ liệu thấp vì dữ liệu của bạn được trải rộng trên nhiều trang hơn mức cần thiết. Do đó, việc đọc dữ liệu đòi hỏi nhiều IO hơn vì dữ liệu được trải rộng trên nhiều trang hơn mức cần thiết. Điều này có thể ảnh hưởng đến cả việc đọc logic và vật lý. Nếu bạn đang xem kết quả từ sys.dm_db_index_physical_stats, con số này là avg_page_space_used_in_percentcột. Cột này chỉ được điền khi sử dụng SAMPLEDhoặc DETAILEDchế độ.

Vậy bạn sẽ làm gì với nó:

Phân mảnh vật lý : Nếu bạn chỉ đơn giản là theo đuổi số lượng cao avg_fragmentation_in_percent, hãy thực sự cân nhắc nếu bạn đang lãng phí thời gian. Đảm bảo rằng bạn có một truy vấn thực tế hoạt động kém và sử dụng môi trường kiểm tra để xác nhận rằng bạn đang khắc phục sự cố bằng cách loại bỏ phân mảnh.

Bạn có thể giải quyết sự phân mảnh vật lý bằng cách làm ALTER INDEX...REORGANIZE. Các REORGANIZEhoạt động trực tuyến, di chuyển các trang cùng một lúc sắp xếp lại cho trở lại vào thứ tự vật lý. Nếu bạn giết một REORGANIZEphần của câu lệnh, bất kỳ tác phẩm nào đã được thực hiện đều được duy trì - chỉ một trang hiện đang được di chuyển sẽ được khôi phục. Thực hiện REORGANIZEtrên một bảng lớn bị phân mảnh cao có thể cần nhiều không gian nhật ký giao dịch hơn và trong chế độ khôi phục hoàn toàn có thể tạo ra một số lượng đáng kể các bản sao lưu nhật ký giao dịch. Nó cũng có thể mất nhiều thời gian hơn cho REORGANIZEmột chỉ số phân mảnh cao hơn so với REBUILDnó.

Bạn sẽ thường thấy lời khuyên để thực hiện một REBUILDchỉ số phân mảnh cao, thay vì một REORGANIZE- Điều này là do việc xây dựng lại từ đầu có thể hiệu quả hơn. Tuy nhiên, sắp xếp lại có thể là một hoạt động "trực tuyến hơn" và đôi khi được ưa thích, ngay cả đối với các chỉ mục bị phân mảnh cao.

Phân mảnh mật độ thấp không thể được cố định bởi REORGANIZE. Nó chỉ có thể được sửa chữa bằng cách làm một ALTER INDEX...REBUILD. Bằng cách thực hiện chỉ mục với ONLINE=ON, bạn sẽ có thể giảm thiểu chặn. Tuy nhiên, REBUILDvẫn cần phải khóa trong giây lát để trao đổi chỉ mục cũ cho chỉ mục mới. Trên một hệ thống rất bận rộn, việc đạt được khóa độc quyền này đôi khi có thể là một vấn đề. Bạn sẽ có thể xác nhận nếu bạn gặp phải vấn đề này bằng cách sử dụng một cái gì đó như sp_whoisactive để kiểm tra chặn trong quá trình xây dựng lại của bạn và xem chi tiết về các khóa và chờ đợi. Sử dụng WAIT_AT_LOW_PRIORITYtùy chọn có thể hữu ích nếu bạn biết rằng có một giai đoạn sử dụng thấp sắp tới và việc xây dựng lại của bạn có thể "lẻn" vào trao đổi này khi hoạt động giảm xuống đủ thấp để đạt được khóa đó. Lưu ý rằng chạy dàiREBUILDhoạt động cũng sẽ là một giao dịch mở dài hạn. Các giao dịch mở dài hạn có thể có vấn đề riêng của họ, liên quan đến việc sử dụng / tái sử dụng nhật ký giao dịch. Nếu bạn đang sử dụng phản chiếu hoặc Nhóm sẵn có, cũng có những cân nhắc cho việc làm lại nhật ký giao dịch trên bản sao thứ cấp.


Phân mảnh mật độ thấp (còn gọi là "phân mảnh nội bộ") thường được cố định bởi a REORGANIZE. Từ BOL : "Sắp xếp lại cũng thu gọn các trang chỉ mục." Chà, miễn là FILLFACTOR hiện tại của chỉ số sẽ cho phép mật độ bạn theo sau.
Granger

2

Để ý

Sau bình luận này:

Bạn sẽ mất các hàng được chèn trong quá trình sao chép. Nếu bạn muốn ngăn chặn điều này bằng cách khóa bảng thì bạn sẽ gặp vấn đề tương tự như OP đã nêu trong câu hỏi của mình. Ngoài ra 200Gb sẽ không đến miễn phí :-) - Marco ngày 5 tháng 9 năm 17 lúc 11:18

... Tôi thấy cách tiếp cận này sẽ không hiệu quả.

Tôi sẽ để lại câu trả lời này như một ví dụ về những việc không nên làm.


Nếu bạn có 200 GB GB miễn phí trên Azure DB, bạn có thể lén lút với "xây dựng lại", bằng cách sao chép dữ liệu của bạn vào một bảng hoàn toàn mới và đặt hàng tại đó.

Thử:

  • kịch bản của bạn LiveTablevào một sản phẩm nàoNewTable
  • sao chép LiveTablevàoNewTable
  • đổi tên LiveTablethànhOldTable
  • đổi tên NewTablethànhLiveTable

Rõ ràng, sử dụng tên bảng của bạn thay vì LiveTable.


Oreo, tôi sẽ sử dụng cách tiếp cận tương tự như bạn. Ngay cả khi có các hàng được chèn trong quá trình sao chép, bạn vẫn có thể thêm chúng sau đó khi NewTable đã được đổi tên thành LiveTable. Vấn đề chính bạn tránh ở đây là thời gian chết kéo dài. Bạn thậm chí có thể bcp nó (i / o sao chép vào). Đó không phải là một ý tưởng tồi vì vậy tôi cũng không hiểu downvote :-)
Koen D

1

Lý tưởng nhất, nếu một chỉ mục được thiết kế tốt, chúng ta không cần phải sử dụng cơ chế khóa.

Đối với tôi có vẻ như bạn sẽ cần chấp nhận khóa để chống phân mảnh chỉ mục được nhóm. Nếu có cơ hội tốt để điều này xảy ra một lần nữa, thì hãy nhìn vào việc thiết kế lại chỉ số được nhóm (nó phải hẹp, độc đáo, tĩnh và không ngừng tăng lên).

Tôi không chắc bạn đang sử dụng phiên bản SQL Server nào, nhưng bạn có thể thử các phiên bản sau vào năm 2012:

  • SET DEADLOCK_PRIORITY LOW - Điều này cho động cơ biết rằng việc xây dựng lại chỉ mục sẽ là nạn nhân bế tắc khi / nếu xảy ra.

  • MaxDOP = 1 - Giá trị MaxDOP giới hạn tổng số CPU logic được sử dụng song song để tạo chỉ mục (từ năm 2005 trở lên - Chỉ phiên bản dành cho doanh nghiệp).

Bạn cũng có thể thay đổi cấu hình khóa trang / hàng, nhưng tôi sẽ không làm điều đó mà không kiểm tra. Bạn chỉ có thể làm cho khóa trở nên tồi tệ hơn, đặc biệt nếu đó là một chỉ mục được thiết kế tồi.

Trong năm 2014 trở đi, có một tùy chọn sau đây về cơ bản cho động cơ cho phép các phiên khác được tiến hành và hoạt động chỉ mục trực tuyến phải chờ:

(WAIT_AT_LOW_PRIORITY (MAX_DURATION = 1 MINUTES, ABORT_AFTER_WAIT = SELF))

0

Tôi đã sử dụng cách tiếp cận tương tự như Oreo đã mô tả ở trên với thành công lớn! Điều duy nhất còn thiếu là bạn cần chạy một kịch bản cập nhật sau khi bạn đã sao chép dữ liệu và thực hiện đổi tên lần cuối.

Bản cập nhật sẽ như thế này:

Insert from OldTable into LiveTable
  Where not exists (select From OldTable Where LiveTable.Key = OldTable.Key)

Nếu Key là cột Danh tính, bạn cần sử dụng một cách tiếp cận hơi khác.


Như đã lưu ý dưới câu trả lời của Oreo, phương pháp của anh ta sẽ không hoạt động nếu vẫn còn dữ liệu được thêm vào bảng gốc, trừ khi bạn khóa bảng gốc đánh bại mục đích của bài tập
Tom V - thử topanswers.xyz

-2

Cố gắng sử dụng shending để phân phối dữ liệu của cơ sở dữ liệu của bạn theo địa lý. Sau đó, bạn sẽ có thể xác định các cửa sổ bảo trì khác nhau cho từng vị trí địa lý và thời gian để bảo trì sẽ ngắn hơn. Điều này cũng sẽ cải thiện hiệu suất. Bạn có thể tìm hiểu thêm về điều này bài viết. Đừng đợi cơ sở dữ liệu lớn hơn.

Với cơ sở dữ liệu lớn và người dùng được kết nối 24 x 7, bạn cần sử dụng sắp xếp lại chỉ mục và chỉ cập nhật số liệu thống kê cần cập nhật (sp_updatestats) để giảm thiểu thời gian cần thiết để bảo trì và tác động đến người dùng.

Hi vọng điêu nay co ich.

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.