Hiệu suất chèn tăng dưới tải: Tại sao?


19

Tôi có một đoạn mã thực hiện chèn vào các bảng không chuẩn hóa cao. Các bảng có số lượng cột từ ~ 100 đến 300+. Đây là SQL Server 2008 R2, chạy trên Windows Server 2008.

Mỗi lần chèn bao gồm việc chèn vào một số bảng trong cùng một giao dịch. Một số chèn được NHibernate bó, nhưng một số không thể được, nhưng tất cả chúng đều theo cùng một giao dịch.

Khi tôi thực hiện các thao tác chèn trong 500 lần bằng cách gọi liên tục một đoạn mã thực hiện thao tác chèn, tôi nhận được trung bình ~ 360 ms.

Điều kỳ lạ là, khi tôi chạy mã kiểm tra đồng thời bằng 4 quy trình (cùng một exe chạy từ 4 dấu nhắc lệnh khác nhau trong windows server 2008), hiệu suất chèn trên mỗi cuộc gọi sẽ tốt hơn nhiều. Tôi thấy các vụ nổ nhanh đến 90 ms (gần như nhanh hơn X4). Tôi đang đo thời gian chèn từ mã.

Vì 4 quy trình không biết gì về nhau, tôi cho rằng điều này có liên quan đến SQL Server, nhưng tôi hoàn toàn không biết tại sao. Tôi muốn biết lý do tại sao điều này xảy ra và nếu có bất kỳ cấu hình nào cho phép tôi có được hiệu suất tương tự khi việc chèn không thường xuyên.

Các đề xuất về các phương pháp giám sát SQL Server để hiểu những gì đang diễn ra ở cấp db cũng được hoan nghênh như nhau.

Câu trả lời:


15

Một lý do có thể là bốn quy trình đồng thời tạo ra một mô hình nhật ký thuận lợi hơn - thường có nghĩa là mỗi lần ghi nhật ký ghi nhiều dữ liệu hơn so với trường hợp với một quy trình thực thi.

Để xác định xem thông lượng / kích thước nhật ký giao dịch có phải là một yếu tố hay không, hãy theo dõi:

Tìm kiếm các giới hạn nội bộ đang đạt được. Trong SQL Server 2008 R2, có thể có tối đa 32 I / O xuất hiện nhật ký (không đồng bộ) trên mỗi cơ sở dữ liệu trên các phiên bản 64 bit (chỉ 8 trên 32 bit). Ngoài ra còn có giới hạn tổng kích thước trên các IO nổi bật là 3840KB.

Thêm thông tin và đọc thêm:


12

Mọi thứ @PaulWhite nói, cộng với ...

Nếu bạn có khóa ngoại tại chỗ, mọi thao tác chèn sẽ yêu cầu kiểm tra trên mỗi bảng được tham chiếu. Tôi nghe có vẻ giống như bạn, vì bạn chỉ nhận được 360ms, điều này khiến tôi cảm thấy chậm chạp.

Dù sao, việc kiểm tra các bảng đó được trợ giúp ồ ạt bằng cách có dữ liệu đó trong RAM, thay vì phải tải nó vào đĩa.

Đối với tôi có vẻ như việc tải dữ liệu vào RAM là một phần quan trọng trong quá trình thực thi của bạn và rằng nó chỉ cần xảy ra một lần.

Nó cũng có thể là bộ nhớ đệm kế hoạch hiệu quả và các truy vấn của bạn cần được biên dịch lần đầu tiên, với các cuộc gọi tiếp theo có thể tránh được giai đoạn đó.


Cảm ơn Rob. Vấn đề về hiệu năng của tôi liên quan đến số lượng bảng được sử dụng nhiều trong quá trình chèn. Không có khóa ngoại, tôi đã xóa chúng vì lý do hiệu suất và các yêu cầu về mô hình và tên miền của tôi cho phép tôi làm điều đó. Tôi không tải dữ liệu vào RAM và các phần chèn của tôi được định hình linh hoạt bởi các yêu cầu đến, chúng luôn thay đổi. Về cơ bản, tôi đang sử dụng lược đồ sao / bông tuyết (OL) cho OLTP và cố gắng thoát khỏi hiệu suất tốt nhất có thể.
mahonya

2
@mahonya, mặc dù bạn không tải dữ liệu vào RAM một cách rõ ràng, trước tiên SQL Server phải đọc các trang chỉ mục và dữ liệu cần thiết vào bộ đệm bộ đệm trước khi thực hiện thao tác chèn. Các luồng chèn đồng thời có thể có tác dụng làm ấm bộ đệm sao cho một luồng phát sinh chi phí đọc và các luồng khác truy cập dữ liệu trong bộ đệm.
Dan Guzman

Cảm ơn @DanGuzman - và vâng, mahonya, rất có thể bộ nhớ cache của bạn đang được làm ấm độc đáo. Tôi sẽ kiểm tra sự chờ đợi của bạn để xem liệu I / O vật lý có gây ra tắc nghẽn của bạn không.
Rob Farley

Cảm ơn @DanGuzman Đồng ý, việc tăng tốc bộ đệm chỉ mục db là thứ mà tôi thường thấy trong các bài đăng có lẽ tôi đã hiểu nhầm đầu vào của Rob.
mahonya

-3

một số máy chủ / cpus / os nhớ các mẫu. như bộ nhớ cache.

Vì bạn làm điều tương tự 4 lần, tôi chắc chắn có những cách nó có thể cắt góc, điều tôi đoán là cách đầu tiên bạn làm, nó nghĩ về nó như một quá trình dài (ví dụ1) nhưng theo cách thứ hai sẽ thấy mã được sử dụng lại và chạy nó như bộ đệm (example2) hoặc nó có thể là quá trình đầu tiên là lớn để phù hợp với tất cả trong (ram example3).

ví dụ1: 0111110000110111110000111011111000011110111110000

ví dụ2: 0111110000 | 11 | 0111110000 | 111 | 0111110000 | 1111 | 0111110000

example3: 0111110000011111000001111100000111110000 example3: vòng lặp: 0111110000

Tôi biết máy chủ ubfox thực hiện điều này với các truy vấn mysql lặp đi lặp lại. Tôi có thể lưu chúng trong bộ nhớ cache, mặc dù thực sự sự khác biệt duy nhất về thời gian là 10-40mm nhưng nó cộng lại. Khi tôi còn đi học, có những lớp cho thấy bạn phải tạo ra các chương trình (perl / php) sử dụng bộ đệm đó để nhanh hơn.

Nhưng, nó có thể phụ thuộc vào chương trình, ngôn ngữ là gì, được biên dịch trong hoặc cách lập trình.

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.