2012-01-04 23 views
6

Tôi có một bảng lớn (~ 170 triệu hàng, 2 nvarchar và 7 cột int) trong SQL Server 2005 liên tục được chèn vào. Tất cả mọi thứ hoạt động ok với nó từ một quan điểm hiệu suất, nhưng mỗi một lần trong một thời gian tôi phải cập nhật một tập hợp các hàng trong bảng gây ra vấn đề. Nó hoạt động tốt nếu tôi cập nhật một bộ dữ liệu nhỏ, nhưng nếu tôi phải cập nhật một bộ 40.000 bản ghi hoặc vì vậy phải mất khoảng 3 phút và các khối trên bảng gây ra vấn đề kể từ khi chèn bắt đầu thất bại.Chạy Cập nhật trên một bảng lớn, được sử dụng nhiều

Nếu tôi chỉ chạy một lựa chọn để lấy lại dữ liệu cần được cập nhật, tôi lấy lại 40k bản ghi trong khoảng 2 giây. Nó chỉ là bản cập nhật kéo dài mãi mãi. Điều này được phản ánh trong kế hoạch thực hiện cho bản cập nhật nơi cập nhật chỉ mục nhóm chiếm 90% chi phí và chỉ mục tìm kiếm và toán tử hàng đầu để có được các hàng chiếm 10% chi phí. Cột tôi đang cập nhật không phải là một phần của bất kỳ khóa chỉ mục nào, do đó, nó không giống như việc tổ chức lại bất kỳ thứ gì.

Có ai có bất kỳ ý tưởng nào về cách thức tăng tốc này không? Suy nghĩ của tôi bây giờ là viết một dịch vụ sẽ chỉ thấy khi các cập nhật này xảy ra, kéo trở lại các bản ghi phải được cập nhật, và sau đó lặp lại và cập nhật từng cái một. Điều này sẽ đáp ứng nhu cầu kinh doanh của tôi nhưng đó là một mô-đun khác để duy trì và tôi rất thích nếu tôi có thể sửa lỗi này từ phía DBA của mọi thứ.

Cảm ơn mọi suy nghĩ!

+0

bạn có thể đăng các định nghĩa bảng (bao gồm khóa chính, chỉ số, vv), các bẫy trên bàn, và bản thân truy vấn cập nhật thực tế? – MatBailie

+0

chỉ là một ý tưởng: sharding – Adrian

+0

@Adrian - Nhưng nếu các trường được cập nhật không nằm trong chỉ mục nhóm (hoặc rõ ràng là bất kỳ chỉ mục nào khác) thì tại sao kế hoạch thực thi lại hiển thị cập nhật chỉ mục nhóm? – MatBailie

Trả lời

0

Cách thức cơ bản của lực lượng vũ phu (và đơn giản nhất) là có một dịch vụ cơ bản, như bạn đã đề cập. Điều đó có lợi thế là có thể mở rộng với tải trên máy chủ và/hoặc tải dữ liệu.

Ví dụ: nếu bạn có một tập hợp các bản cập nhật phải xảy ra ASAP, thì bạn có thể bật kích thước lô. Ngược lại, đối với các bản cập nhật ít quan trọng hơn, bạn có thể cập nhật "máy chủ" chậm lại nếu mỗi lần cập nhật mất quá nhiều thời gian "" để giảm bớt áp lực lên DB.

Quá trình "nhịp tim" này khá phổ biến trong các hệ thống và có thể là rất mạnh mẽ trong các tình huống phù hợp.

1

Thực ra nó có thể sắp xếp lại các trang nếu bạn cập nhật cột nvarchar. Tùy thuộc vào những gì cập nhật đối với các cột này, chúng có thể làm cho bản ghi phát triển lớn hơn không gian dành riêng cho bản cập nhật trước khi cập nhật. (Xem giải thích ngay bây giờ nvarchar được lưu trữ tại http://www.databasejournal.com/features/mssql/physical-database-design-consideration.html.)

Vì vậy, nói một bản ghi có chuỗi 20 ký tự được lưu trong nvarchar - điều này sẽ mất 20 * 2 + 2 (2 cho con trỏ) byte trong không gian. Điều này được viết tại chèn ban đầu vào bảng của bạn (dựa trên cấu trúc chỉ mục). SQL Server sẽ chỉ sử dụng nhiều không gian như nvarchar của bạn thực sự mất.

Bây giờ đến bản cập nhật và chèn một chuỗi gồm 40 ký tự. Và oops, không gian cho các bản ghi trong cấu trúc lá của bạn chỉ số của bạn đột nhiên là quá nhỏ. Vì vậy, tắt đi kỷ lục đến một nơi vật lý khác nhau với một con trỏ ở nơi cũ chỉ đến nơi thực tế của hồ sơ cập nhật.

Điều này sau đó làm cho chỉ mục của bạn bị lỗi thời và vì toàn bộ cấu trúc vật lý yêu cầu thay đổi bạn sẽ thấy rất nhiều công việc lập chỉ mục diễn ra phía sau hậu trường. Rất có thể gây ra leo thang khóa bảng độc quyền.

Không chắc chắn cách tốt nhất để giải quyết vấn đề này. Cá nhân nếu có thể tôi lấy một khóa bảng độc quyền, thả chỉ mục, làm các bản cập nhật, reindex. Bởi vì các cập nhật của bạn đôi khi làm cho chỉ mục bị lỗi thời, đây có thể là tùy chọn nhanh nhất. Tuy nhiên điều này đòi hỏi một cửa sổ bảo trì.

+0

Bạn cũng có thể DISABLE một chỉ mục trước khi thực hiện các cập nhật để tránh việc xây dựng lại nó. Các khóa PAGE-> TABLE - chúng tôi có một số lượng lớn các khóa PAGE rõ ràng ở đây ASFAS tôi nhận được nó. Các bản ghi 170m sẽ khó bị chặn bởi 40k hồ sơ mặc dù nó sẽ> 5k ổ khóa! :)). Ngoài ra, tôi cũng khuyên bạn nên THAM GIA bảng lớn này, nó không được thực hiện YET. Cảm ơn bạn tình. –

+0

Bản cập nhật không chạm vào cột nvarchar, chỉ là các cột int để dữ liệu không được sắp xếp lại. @Sergey, tôi nhìn vào phân vùng, nhưng tôi không thấy một cách tốt để duy trì các phân vùng. Nó có thể sẽ đáp ứng nhu cầu hiệu suất của tôi, nhưng sẽ đi kèm với một chút hành lý bảo trì. – kylememe

0

Dây có dây mà máy phân tích của bạn đang nói rằng cần có thời gian để cập nhật chỉ mục nhóm. Kích thước của dữ liệu có thay đổi khi bạn cập nhật không? Có vẻ như các varchar là lái xe dữ liệu được tổ chức lại mà có thể cần cập nhật cho con trỏ chỉ mục (Như KMB đã được chỉ ra). Trong trường hợp đó, bạn có thể muốn tăng% kích thước miễn phí trên dữ liệu và các trang chỉ mục để dữ liệu và các trang chỉ mục có thể phát triển mà không cần tái phát/phân bổ lại. Kể từ khi cập nhật là một hoạt động chuyên sâu IO (không giống như đọc, có thể được đệm) hiệu suất cũng phụ thuộc vào một số yếu tố

1) Bảng của bạn có được phân đoạn bằng dữ liệu 2) Toàn bộ bảng nằm trong cùng một đĩa SAN hay không SAN sọc tốt?) 3) Làm thế nào tiết là đăng nhập giao dịch. Kích thước bộ đệm của loggin giao dịch có tăng lên để hỗ trợ ghi lớn hơn vào nhật ký để hỗ trợ chèn lớn không?

Bạn cũng đang sử dụng API/Ngôn ngữ nào quan trọng? Ví dụ: JDBC hỗ trợ tính năng cập nhật hàng loạt giúp cập nhật một chút hiệu quả nếu bạn đang thực hiện nhiều cập nhật.

1

Bạn nên cập nhật hàng loạt của mình thành một số cập nhật (giả sử 10000 tại một thời điểm, TEST!) Thay vì một bản cập nhật lớn 40 nghìn hàng. Bằng cách này bạn sẽ tránh một khóa bàn, SQL Server sẽ chỉ đưa ra 5000 khóa (trang hoặc hàng) trước khi esclating đến một khóa bảng và thậm chí điều này không phải là rất có thể dự đoán (áp lực bộ nhớ, vv). Cập nhật nhỏ hơn được thực hiện trong fasion này ít nhất sẽ tránh các vấn đề tương tranh mà bạn đang gặp phải.

Bạn có thể thực hiện hàng loạt các bản cập nhật bằng dịch vụ hoặc con trỏ firehose.

đọc này cho biết thêm: http://msdn.microsoft.com/en-us/library/ms184286.aspx

Hope this helps

Robert

Các vấn đề liên quan