Làm thế nào để một người điều tra hiệu suất của một tuyên bố BULK INSERT?


12

Tôi chủ yếu là một nhà phát triển .NET sử dụng Entity Framework ORM. Tuy nhiên, vì tôi không muốn sử dụng ORM , tôi đang cố gắng hiểu những gì xảy ra trong lớp dữ liệu (cơ sở dữ liệu). Về cơ bản, trong quá trình phát triển, tôi khởi động trình lược tả và kiểm tra một số phần của mã tạo ra theo các truy vấn.

Nếu tôi phát hiện ra thứ gì đó cực kỳ phức tạp (ORM có thể tạo ra các truy vấn khủng khiếp ngay cả từ các câu lệnh LINQ khá đơn giản, nếu không được viết cẩn thận) và / hoặc nặng (thời lượng, CPU, trang đọc), tôi sẽ đưa nó vào SSMS và kiểm tra kế hoạch thực hiện của nó.

Nó hoạt động tốt cho mức độ kiến ​​thức cơ sở dữ liệu của tôi. Tuy nhiên, BULK INSERT dường như là một sinh vật đặc biệt, vì nó dường như không tạo ra SHOWPLAN .

Tôi sẽ cố gắng minh họa một ví dụ rất đơn giản:

Bảng định nghĩa

CREATE TABLE dbo.ImportingSystemFileLoadInfo
(
    ImportingSystemFileLoadInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ImportingSystemFileLoadInfo PRIMARY KEY CLUSTERED,
    EnvironmentId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo REFERENCES dbo.Environment,
    ImportingSystemId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo_ImportingSystem REFERENCES dbo.ImportingSystem,
    FileName NVARCHAR(64) NOT NULL,
FileImportTime DATETIME2 NOT NULL,
    CONSTRAINT UQ_ImportingSystemImportInfo_EnvXIs_TableName UNIQUE (EnvironmentId, ImportingSystemId, FileName, FileImportTime)
)

Lưu ý: không có chỉ mục nào khác được xác định trên bảng

Chèn số lượng lớn (những gì tôi bắt được trong profiler, chỉ một đợt)

insert bulk [dbo].[ImportingSystemFileLoadInfo] ([EnvironmentId] Int, [ImportingSystemId] Int, [FileName] NVarChar(64) COLLATE Latin1_General_CI_AS, [FileImportTime] DateTime2(7))

Số liệu

  • 695 mặt hàng được chèn
  • CPU = 31
  • Đọc = 4271
  • Viết = 24
  • Thời lượng = 154
  • Tổng số bảng = 11500

Đối với ứng dụng của tôi, điều đó không sao, mặc dù số lần đọc có vẻ khá lớn (tôi biết rất ít về nội bộ của SQL Server, vì vậy tôi so sánh với kích thước trang 8K và thông tin bản ghi nhỏ tôi có)

Câu hỏi: làm thế nào tôi có thể điều tra nếu BULK INSERT này có thể được tối ưu hóa? Hoặc nó không có nghĩa gì cả, vì nó được cho là cách nhanh nhất để đẩy dữ liệu lớn từ ứng dụng khách sang SQL Server?

Câu trả lời:


14

Theo như tôi có thể nói với bạn, bạn có thể tối ưu hóa một phần chèn hàng loạt theo cách rất giống với cách bạn tối ưu hóa một phần chèn thông thường. Thông thường, một kế hoạch truy vấn cho một chèn đơn giản không có nhiều thông tin vì vậy đừng lo lắng về việc không có kế hoạch. Tôi sẽ xem xét một số cách tối ưu hóa phần chèn nhưng hầu hết trong số chúng có thể không áp dụng cho phần chèn bạn đã chỉ định trong câu hỏi. Tuy nhiên, chúng có thể hữu ích nếu trong tương lai bạn cần tải lượng dữ liệu lớn hơn.

1. Chèn dữ liệu theo thứ tự khóa cụm

SQL Server sẽ thường sắp xếp dữ liệu trước khi chèn nó vào một bảng có chỉ mục được nhóm. Đối với một số bảng và ứng dụng, bạn có thể cải thiện hiệu suất bằng cách sắp xếp dữ liệu trong tệp phẳng và cho SQL Server biết rằng dữ liệu được sắp xếp thông qua ORDERđối số BULK INSERT:

ĐẶT HÀNG ({cột [ASC | DESC]} [, ... n])

Chỉ định cách sắp xếp dữ liệu trong tệp dữ liệu. Hiệu suất nhập hàng loạt được cải thiện nếu dữ liệu được nhập được sắp xếp theo chỉ mục được nhóm trên bảng, nếu có.

Vì bạn đang sử dụng một IDENTITYcột làm khóa cụm, bạn không cần phải lo lắng về điều này.

2. Sử dụng TABLOCKnếu có thể

Nếu bạn được đảm bảo chỉ có một phiên chèn dữ liệu vào bảng của mình, bạn có thể chỉ định TABLOCKđối số cho BULK INSERT. Điều này có thể làm giảm sự tranh chấp khóa và có thể dẫn đến đăng nhập tối thiểu trong một số tình huống. Tuy nhiên, bạn đang chèn vào một bảng có chỉ mục được nhóm chứa dữ liệu để bạn sẽ không nhận được ghi nhật ký tối thiểu mà không có cờ theo dõi 610 được đề cập sau trong câu trả lời này.

Nếu TABLOCKkhông thể, bởi vì bạn không thể thay đổi mã , không phải tất cả hy vọng đều bị mất. Cân nhắc sử dụng sp_table_option:

EXEC [sys].[sp_tableoption]
    @TableNamePattern = N'dbo.BulkLoadTable' ,
    @OptionName = 'table lock on bulk load' , 
    @OptionValue = 'ON'

Một tùy chọn khác là bật cờ theo dõi 715 .

3. Sử dụng cỡ lô thích hợp

Đôi khi bạn sẽ có thể điều chỉnh các phần chèn bằng cách thay đổi kích thước lô.

ROWS_PER_BATCH = rows_per_batch

Cho biết số lượng hàng dữ liệu gần đúng trong tệp dữ liệu.

Theo mặc định, tất cả dữ liệu trong tệp dữ liệu được gửi đến máy chủ dưới dạng một giao dịch và số lượng hàng trong lô không xác định đối với trình tối ưu hóa truy vấn. Nếu bạn chỉ định ROWS_PER_BATCH (có giá trị> 0), máy chủ sẽ sử dụng giá trị này để tối ưu hóa hoạt động nhập hàng loạt. Giá trị được chỉ định cho ROWS_PER_BATCH sẽ xấp xỉ bằng số lượng hàng thực tế. Để biết thông tin về các cân nhắc về hiệu suất, xem "Ghi chú", sau trong chủ đề này.

Đây là trích dẫn từ sau trong bài viết:

Nếu số lượng trang được xóa trong một lô vượt quá ngưỡng bên trong, có thể quét toàn bộ nhóm bộ đệm để xác định trang nào sẽ bị xóa khi lô được thực hiện. Quét toàn bộ này có thể làm tổn thương hiệu suất nhập hàng loạt. Một trường hợp có khả năng vượt quá ngưỡng nội bộ xảy ra khi nhóm bộ đệm lớn được kết hợp với hệ thống con I / O chậm. Để tránh tràn bộ đệm trên các máy lớn, không sử dụng gợi ý TABLOCK (sẽ loại bỏ tối ưu hóa hàng loạt) hoặc sử dụng kích thước lô nhỏ hơn (bảo tồn tối ưu hóa hàng loạt).

Vì máy tính khác nhau, chúng tôi khuyên bạn nên kiểm tra các kích cỡ lô khác nhau với tải dữ liệu của mình để tìm ra cách nào phù hợp nhất với bạn.

Cá nhân tôi sẽ chỉ chèn tất cả 695 hàng trong một lô. Điều chỉnh kích thước lô có thể tạo ra sự khác biệt lớn khi chèn nhiều dữ liệu.

4. Hãy chắc chắn rằng bạn cần IDENTITYcột

Tôi không biết gì về mô hình dữ liệu hoặc yêu cầu của bạn, nhưng đừng rơi vào cái bẫy thêm IDENTITYcột vào mỗi bảng. Aaron Bertrand có một bài viết về điều này được gọi là thói quen xấu để đá: đặt một cột IDENTITY trên mỗi bàn . Để rõ ràng, tôi không nói rằng bạn nên xóa IDENTITYcột khỏi bảng này. Tuy nhiên, nếu bạn xác định rằng IDENTITYcột là không cần thiết và loại bỏ nó có thể cải thiện hiệu suất chèn.

5. Vô hiệu hóa các chỉ mục hoặc các ràng buộc

Nếu bạn đang tải một lượng lớn dữ liệu vào một bảng so với những gì bạn đã có thì có thể nhanh hơn để vô hiệu hóa các chỉ mục hoặc các ràng buộc trước khi tải và để bật chúng sau khi tải. Đối với lượng dữ liệu lớn, SQL Server thường không hiệu quả hơn khi xây dựng một chỉ mục cùng một lúc thay vì dữ liệu được tải vào bảng. Có vẻ như bạn đã chèn 695 hàng vào một bảng có 11500 hàng, vì vậy tôi không khuyến nghị kỹ thuật này.

6. Xem xét TF 610

Trace Flag 610 cho phép đăng nhập tối thiểu trong một số tình huống bổ sung. Đối với bảng của bạn có IDENTITYkhóa được nhóm, bạn sẽ có được ghi nhật ký tối thiểu cho bất kỳ trang dữ liệu mới nào miễn là mô hình khôi phục của bạn đơn giản hoặc được ghi nhật ký hàng loạt. Tôi tin rằng tính năng này không được bật theo mặc định vì nó có thể làm giảm hiệu suất trên một số hệ thống. Bạn sẽ cần phải kiểm tra cẩn thận trước khi bật cờ theo dõi này. Tham chiếu được đề xuất của Microsoft vẫn xuất hiện là Hướng dẫn hiệu suất tải dữ liệu

Tác động I / O của việc ghi nhật ký tối thiểu theo cờ dấu vết 610

Khi bạn cam kết giao dịch tải hàng loạt được ghi lại tối thiểu, tất cả các trang được tải phải được xóa vào đĩa trước khi cam kết hoàn thành. Bất kỳ trang bị xóa nào không được bắt bởi một thao tác điểm kiểm tra trước đó có thể tạo ra rất nhiều I / O ngẫu nhiên. Tương phản điều này với một hoạt động được ghi lại đầy đủ, tạo ra I / O tuần tự trên ghi nhật ký thay vào đó và không yêu cầu các trang được tải phải được xóa vào đĩa tại thời điểm cam kết.

Nếu kịch bản tải của bạn là các thao tác chèn nhỏ trên btrees không vượt qua ranh giới điểm kiểm tra và bạn có hệ thống I / O chậm, sử dụng ghi nhật ký tối thiểu thực sự có thể làm chậm tốc độ chèn.

Theo như tôi có thể nói điều này không liên quan gì đến cờ dấu vết 610, mà là với bản ghi nhật ký tối thiểu. Tôi tin rằng trích dẫn trước đây về ROWS_PER_BATCHđiều chỉnh đã nhận được cùng một khái niệm.

Tóm lại, có lẽ bạn không thể làm gì nhiều để điều chỉnh BULK INSERT. Tôi sẽ không quan tâm đến số lượng đọc mà bạn quan sát thấy với phần chèn của bạn. SQL Server sẽ báo cáo đọc bất cứ khi nào bạn chèn dữ liệu. Hãy xem xét những điều sau đây rất đơn giản INSERT:

DROP TABLE IF EXISTS X_TABLE;

CREATE TABLE X_TABLE (
VAL VARCHAR(1000) NOT NULL
);

SET STATISTICS IO, TIME ON;

INSERT INTO X_TABLE WITH (TABLOCK)
SELECT REPLICATE('Z', 1000)
FROM dbo.GetNums(10000); -- generate 10000 rows

Đầu ra từ SET STATISTICS IO, TIME ON:

Bảng 'X_TABLE'. Quét số 0, logic đọc 11,28

Tôi có 11,28 báo cáo đọc nhưng đó không phải là thông tin hành động. Đôi khi số lần đọc được báo cáo có thể được giảm bằng cách ghi nhật ký tối thiểu, nhưng tất nhiên sự khác biệt không thể được dịch trực tiếp thành mức tăng hiệu suất.


12

Tôi sẽ bắt đầu trả lời câu hỏi này, với ý định liên tục cập nhật câu trả lời này khi tôi xây dựng một nền tảng kiến ​​thức về các thủ thuật. Hy vọng rằng những người khác đi qua điều này và giúp tôi cải thiện kiến ​​thức của riêng tôi trong quá trình này.

  1. Kiểm tra ruột: Tường lửa của bạn có thực hiện kiểm tra gói sâu, trạng thái không? Bạn sẽ không tìm thấy nhiều trên Internet về vấn đề này, nhưng nếu số lượng chèn của bạn chậm hơn khoảng 10 lần so với mức cần thiết, thì rất có thể bạn có một thiết bị bảo mật thực hiện kiểm tra gói sâu Cấp độ 3- và kiểm tra "Ngăn ngừa SQL SQL chung ".

  2. Đo kích thước của dữ liệu bạn dự định chèn hàng loạt, tính bằng byte, mỗi lô. Và kiểm tra xem bạn có đang lưu trữ bất kỳ dữ liệu LOB nào không, vì đó là một hoạt động tìm và ghi trang riêng biệt.

    Một số lý do tại sao bạn nên làm theo cách này:

    a. Trong AWS, IOPS lưu trữ khối đàn hồi được chia thành các byte, không phải hàng.

    1. Xem Hiệu suất âm lượng của Amazon EBS trên các trường hợp Linux »Đặc điểm và giám sát I / O để biết giải thích về đơn vị IOPS của EBS là gì
    2. Cụ thể, khối lượng SSD mục đích chung (gp2) có khái niệm "Tín dụng I / O và hiệu suất bùng nổ" và thông thường đối với việc xử lý ETL nặng để làm mất tín dụng số dư. Thời lượng cụm của bạn được đo bằng byte, không phải hàng SQL Server :)

    b. Mặc dù hầu hết các thư viện hoặc trang trắng kiểm tra dựa trên số lượng hàng, nhưng đó thực sự là số trang có thể được viết cho vấn đề đó và để tính toán điều đó, bạn cần biết có bao nhiêu byte trên mỗi hàng và kích thước trang của bạn (thường là 8KB , nhưng luôn kiểm tra kỹ nếu bạn thừa hưởng hệ thống từ người khác.)

    SELECT *
    FROM 
    sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N'YourTable'), NULL, NULL, 'DETAILED')
    

    Hãy chú ý đến avg_record_size_in_bytes và page_count.

    c. Như Paul White giải thích trong https://sqlperformance.com/2019/05/sql-performance/minimal-logging-insert-select-heap , "Để cho phép đăng nhập tối thiểu INSERT...SELECT, SQL Server phải mong đợi hơn 250 hàng với tổng kích thước ít nhất một mức độ (8 trang). "

  3. Nếu bạn có bất kỳ chỉ mục nào có các ràng buộc kiểm tra hoặc các ràng buộc duy nhất, hãy sử dụng SET STATISTICS IO ONSET STATISTICS TIME ON(hoặc SQL Server Profiler hoặc SQL Server Extended Events) để nắm bắt thông tin như liệu phần chèn hàng loạt của bạn có bất kỳ thao tác đọc nào không. Các hoạt động đọc là do công cụ cơ sở dữ liệu SQL Server đảm bảo các ràng buộc toàn vẹn vượt qua.

  4. Hãy thử tạo một cơ sở dữ liệu thử nghiệm trong đó PRIMARYFILEGROUP được gắn trên ổ đĩa RAM. Điều này sẽ nhanh hơn một chút so với SSD nhưng cũng loại bỏ bất kỳ câu hỏi nào về việc Bộ điều khiển RAID của bạn có thể thêm chi phí không. Trong năm 2018, không nên, nhưng bằng cách tạo nhiều đường cơ sở khác nhau như thế này, bạn có thể có được một ý tưởng chung về việc phần cứng của bạn được thêm vào bao nhiêu.

  5. Cũng đặt tập tin nguồn vào ổ đĩa RAM là tốt.

    Đặt tệp nguồn vào Ổ đĩa RAM sẽ loại trừ mọi sự cố tranh chấp nếu bạn đang đọc tệp nguồn từ cùng ổ đĩa đó, tệp FILEGROUP của máy chủ cơ sở dữ liệu của bạn được bật.

  6. Xác minh rằng bạn đã định dạng ổ cứng của mình bằng cách sử dụng mức độ 64KB.

  7. Sử dụng UserBenchmark.com và điểm chuẩn SSD của bạn. Điều này sẽ:

    1. Thêm kiến ​​thức cho những người hâm mộ hiệu suất khác về hiệu suất mong đợi từ một thiết bị
    2. Giúp bạn biết liệu hiệu suất của ổ đĩa của bạn có kém hiệu quả với các ổ đĩa chính xác không
    3. Giúp bạn tìm hiểu xem hiệu suất của ổ đĩa của bạn có hoạt động kém hơn các ổ đĩa khác trong cùng thể loại (SSD, HDD, v.v.)
  8. Nếu bạn đang gọi "INSERT BULK" từ C # thông qua Tiện ích mở rộng khung thực thể, thì hãy đảm bảo bạn "làm nóng" JIT trước và "vứt bỏ" vài kết quả đầu tiên.

  9. Hãy thử tạo Bộ đếm hiệu suất cho chương trình của bạn. Với .NET, bạn có thể sử dụng điểm chuẩn .NET và nó sẽ tự động cấu hình một loạt các số liệu cơ bản. Sau đó, bạn có thể CHIA SẺ các nỗ lực trình hồ sơ của mình với cộng đồng nguồn mở và xem mọi người chạy các phần cứng khác nhau có báo cáo cùng một số liệu hay không (viz. Từ quan điểm trước đây của tôi về việc sử dụng UserBenchmark.com để so sánh).

  10. Hãy thử sử dụng các ống có tên và chạy nó như localhost.

  11. Nếu bạn đang nhắm mục tiêu SQL Server và sử dụng .NET Core, hãy xem xét việc khởi động Linux với SQL Server Std Edition - chi phí này ít hơn một đô la mỗi giờ ngay cả đối với phần cứng nghiêm trọng. Ưu điểm chính của việc thử cùng một mã với cùng một phần cứng với một HĐH khác là xem liệu ngăn xếp TCP / IP của nhân hệ điều hành có gây ra sự cố hay không.

  12. Sử dụng Truy vấn chẩn đoán máy chủ SQL của Glen Barry để đo độ trễ ổ đĩa cho ổ đĩa lưu trữ FILEGROUP của bảng cơ sở dữ liệu của bạn.

    a. Hãy chắc chắn để đo trước khi kiểm tra của bạn, và sau khi kiểm tra của bạn. "Trước bài kiểm tra của bạn" chỉ cho bạn biết liệu bạn có các đặc điểm IO khủng khiếp làm cơ sở hay không.

    b. Để đo "trong quá trình kiểm tra của bạn", bạn thực sự cần sử dụng Bộ đếm hiệu suất PerfMon.

    Tại sao? Bởi vì hầu hết các máy chủ cơ sở dữ liệu đều sử dụng một số loại lưu trữ gắn mạng (NAS). Trong đám mây, trong AWS, Storage Block Storage chỉ có thế. Bạn có thể bị ràng buộc bởi IOPS của giải pháp âm lượng / NAS EBS của bạn.

  13. Sử dụng một số công cụ để đo lường số liệu thống kê chờ đợi. Màn hình SQL của Red Gate , Trình phân tích hiệu suất cơ sở dữ liệu của SolarWinds hoặc thậm chí các truy vấn chẩn đoán máy chủ SQL của Glen Barry hoặc truy vấn Thống kê Chờ của Paul Randal .

    a. Các loại chờ phổ biến nhất có thể sẽ là Bộ nhớ / CPU, WRITELOG, PAGEIOLATCH_EX và ASYNC_NETWORK_IO .

    b. Bạn có thể phải chịu các loại chờ bổ sung nếu bạn đang chạy Nhóm sẵn có.

  14. Đo lường tác động của nhiều INSERT BULKlệnh đồng thời TABLOCKbị vô hiệu hóa (TABLOCK sẽ có khả năng buộc tuần tự hóa các lệnh INSERT BULK). Nút cổ chai của bạn có thể chờ đợi INSERT BULKđể hoàn thành; bạn nên cố gắng xếp hàng nhiều tác vụ như mô hình dữ liệu vật lý của máy chủ cơ sở dữ liệu của bạn có thể xử lý.

  15. Xem xét phân vùng bảng của bạn. Như một ví dụ cụ thể: nếu bảng cơ sở dữ liệu của bạn chỉ là phần phụ, Andrew Novick đã đề xuất tạo một "HÔM NAY" FILEGROUPvà phân vùng thành ít nhất hai nhóm fileg, NGAY HÔM NAY và TRƯỚC KHI. Theo cách này, nếu INSERT BULKdữ liệu của bạn chỉ là dữ liệu cho ngày hôm nay, bạn có thể lọc trên trường createdOn để buộc tất cả các phần chèn vào một lần duy nhất FILEGROUPvà do đó giảm chặn khi sử dụng TABLOCK. Kỹ thuật này được mô tả chi tiết hơn trong Microsoft Whitepaper: Bảng phân vùng và chiến lược chỉ mục bằng SQL Server 2008

  16. Nếu bạn đang sử dụng các chỉ mục của cột, hãy tắt TABLOCKvà tải dữ liệu theo 102.400 hàng Batch Size. Sau đó, bạn có thể tải tất cả dữ liệu của mình song song trực tiếp vào các nhóm hàng của cột. Đề xuất này (và được ghi lại hợp lý) xuất phát từ các chỉ mục Cột của Microsoft - Hướng dẫn tải dữ liệu :

    Tải hàng loạt có các tối ưu hóa hiệu suất tích hợp sẵn này:

    Tải song song: Bạn có thể có nhiều tải hàng loạt đồng thời (bcp hoặc chèn số lượng lớn) mà mỗi tải một tệp dữ liệu riêng biệt. Không giống như tải hàng loạt cửa hàng vào SQL Server, bạn không cần chỉ định TABLOCKvì mỗi luồng nhập hàng loạt sẽ tải dữ liệu riêng biệt vào một nhóm hàng riêng biệt (nhóm hàng nén hoặc delta) với khóa độc quyền trên đó. Việc sử dụng TABLOCKsẽ buộc một khóa độc quyền trên bàn và bạn sẽ không thể nhập dữ liệu song song.

    Ghi nhật ký tối thiểu:Tải trọng số lượng lớn sử dụng ghi nhật ký tối thiểu trên dữ liệu đi trực tiếp vào các nhóm hàng được nén. Bất kỳ dữ liệu nào đi đến một nhóm hàng delta được ghi lại đầy đủ. Điều này bao gồm mọi kích thước lô nhỏ hơn 102.400 hàng. Tuy nhiên, với tải số lượng lớn, mục tiêu dành cho hầu hết các dữ liệu để bỏ qua các nhóm hàng delta.

    Tối ưu hóa khóa: Khi tải vào nhóm hàng nén, khóa X trên nhóm hàng được lấy. Tuy nhiên, khi tải số lượng lớn vào nhóm hàng delta, khóa X được lấy tại nhóm hàng nhưng SQL Server vẫn khóa các khóa PAGE / EXTENT vì khóa nhóm X không phải là một phần của phân cấp khóa.

  17. Kể từ SQL Server 2016, không còn cần phải bật cờ theo dõi 610 để đăng nhập tối thiểu vào bảng được lập chỉ mục . Trích dẫn kỹ sư Microsoft Parikshit Sav camera ( nhấn mạnh của tôi ):

    Một trong những mục tiêu thiết kế của SQL Server 2016 là cải thiện hiệu suất và khả năng mở rộng của động cơ ra khỏi hộp để làm cho nó chạy nhanh hơn mà không cần bất kỳ nút bấm hoặc cờ theo dõi nào cho khách hàng. Là một phần của những cải tiến này, một trong những cải tiến được thực hiện trong mã công cụ SQL Server là bật bối cảnh tải hàng loạt (còn được gọi là chèn nhanh hoặc bối cảnh tải nhanh) và ghi nhật ký tối thiểu theo mặc định khi thực hiện các hoạt động tải hàng loạt trên cơ sở dữ liệu đơn giản hoặc mô hình phục hồi đăng nhập số lượng lớn. Nếu bạn không quen với việc ghi nhật ký tối thiểu, tôi khuyên bạn nên đọc bài đăng trên blog này từ Sunil Agrawal nơi anh ấy giải thích cách ghi nhật ký tối thiểu hoạt động trong SQL Server. Để chèn số lượng lớn được ghi lại tối thiểu, nó vẫn cần phải đáp ứng các điều kiện tiên quyết được ghi lại ở đây.

    Là một phần của những cải tiến này trong SQL Server 2016, bạn không còn cần phải bật cờ theo dõi 610 để đăng nhập tối thiểu vào bảng được lập chỉ mụcvà nó tham gia một số cờ theo dõi khác (1118, 1117, 1236, 8048) để trở thành một phần của lịch sử. Trong SQL Server 2016, khi hoạt động tải hàng loạt khiến một trang mới được phân bổ, tất cả các hàng điền tuần tự trang đó sẽ được ghi lại tối thiểu nếu tất cả các điều kiện tiên quyết khác để ghi nhật ký tối thiểu được thảo luận trước đó. Các hàng được chèn vào các trang hiện có (không phân bổ trang mới) để duy trì thứ tự chỉ mục vẫn được ghi lại đầy đủ, cũng như các hàng được di chuyển do chia tách trang trong quá trình tải. Điều quan trọng nữa là phải bật ALLOW_PAGE_LOCKS cho các chỉ mục (được BẬT theo mặc định) để hoạt động ghi nhật ký tối thiểu hoạt động khi khóa trang được lấy trong khi cấp phát và do đó chỉ phân bổ trang hoặc phạm vi được ghi lại.

  18. Nếu bạn đang sử dụng SqlBulkCopy trong C # hoặc EntityFramework.Extensions (sử dụng SqlBulkCopy dưới mui xe), thì hãy kiểm tra cấu hình bản dựng của bạn. Bạn đang chạy thử nghiệm trong chế độ Phát hành? Kiến trúc mục tiêu có được đặt thành Bất kỳ CPU / x64 / x86 không?

  19. Cân nhắc sử dụng sp_who2 để xem liệu giao dịch INSERT BULK có bị BỊ XÓA không. Nó có thể bị TẠM BIỆT vì nó bị chặn bởi một spid khác. Xem xét việc đọc Làm thế nào để giảm thiểu chặn máy chủ SQL . Bạn cũng có thể sử dụng sp_WhoIsActive của Adam Machanic, nhưng sp_who2 sẽ cung cấp cho bạn thông tin cơ bản bạn cần.

  20. Bạn có thể có I / O đĩa xấu. Nếu bạn thực hiện thao tác chèn số lượng lớn và việc sử dụng đĩa của bạn không đạt 100% và bị kẹt ở mức khoảng 2%, thì bạn có thể có chương trình cơ sở xấu hoặc thiết bị I / O bị lỗi. (Điều này đã xảy ra với đồng nghiệp của tôi.) Sử dụng [SSD UserBenchmark] để so sánh với những người khác về hiệu suất phần cứng, đặc biệt là nếu bạn có thể sao chép độ chậm trên máy dev cục bộ của mình. (Tôi đặt cái cuối cùng này trong danh sách vì hầu hết các công ty không cho phép các nhà phát triển chạy cơ sở dữ liệu trên máy cục bộ của họ do rủi ro IP.)

  21. Nếu bảng của bạn sử dụng tính năng nén, bạn có thể thử chạy nhiều phiên và trong mỗi phiên, hãy bắt đầu với việc sử dụng một giao dịch hiện có và chạy giao dịch này trước lệnh SqlBulkCopy:

    THAY ĐỔI QUY TRÌNH THIẾT BỊ CẤU HÌNH MÁY CHỦ CPU = AUTO;

  22. Đối với Tải liên tục, một luồng ý tưởng, lần đầu tiên được phác thảo trong bảng trắng của Microsoft, Bảng phân vùng và Chiến lược chỉ mục bằng SQL Server 2008 :

    Tải liên tục

    Trong kịch bản OLTP, dữ liệu mới có thể xuất hiện liên tục. Nếu người dùng cũng đang truy vấn phân vùng mới nhất, việc chèn dữ liệu liên tục có thể dẫn đến chặn: Truy vấn của người dùng có thể chặn phần chèn và tương tự, phần chèn có thể chặn truy vấn của người dùng.

    Có thể giảm bớt sự tham gia vào bảng tải hoặc phân vùng bằng cách sử dụng cách ly snapshot, cụ thể là READ COMMITTED SNAPSHOTmức cô lập. Khi bị READ COMMITTED SNAPSHOTcô lập, việc chèn vào bảng không gây ra hoạt động trong kho phiên bản tempdb , do đó, chi phí tempdb là tối thiểu để chèn, nhưng không có khóa chia sẻ nào sẽ được thực hiện bởi các truy vấn của người dùng trên cùng một phân vùng.

    Trong các trường hợp khác, khi dữ liệu được chèn vào bảng được phân vùng liên tục ở tốc độ cao, bạn vẫn có thể tạo dữ liệu trong một khoảng thời gian ngắn trong các bảng phân tầng và sau đó chèn dữ liệu đó vào phân vùng mới nhất liên tục cho đến khi cửa sổ cho phân vùng hiện tại đi qua và dữ liệu sau đó được chèn vào phân vùng tiếp theo. Ví dụ: giả sử bạn có hai bảng phân tầng nhận dữ liệu trị giá 30 giây mỗi bảng, trên cơ sở thay thế: một bảng trong nửa đầu của một phút, bảng thứ hai trong nửa sau của một phút. Một thủ tục được lưu trữ chèn xác định nửa phút của phần chèn hiện tại, và sau đó nó chèn vào bảng phân tầng đầu tiên. Khi hết 30 giây, quy trình chèn xác định nó phải chèn vào bảng phân tầng thứ hai. Một thủ tục được lưu trữ khác sau đó tải dữ liệu từ bảng phân tầng đầu tiên vào phân vùng mới nhất của bảng và sau đó nó cắt bớt bảng phân tầng đầu tiên. Sau 30 giây nữa, quy trình được lưu trữ tương tự sẽ chèn dữ liệu từ quy trình được lưu trữ thứ hai và đặt nó vào phân vùng hiện tại, sau đó nó cắt ngắn bảng phân tầng thứ hai.

  23. Hướng dẫn hiệu suất tải dữ liệu của Microsoft CAT Team

  24. Hãy chắc chắn rằng số liệu thống kê của bạn được cập nhật. Sử dụng FULLSCAN nếu bạn có thể sau mỗi lần xây dựng chỉ mục.

  25. Điều chỉnh hiệu suất SAN với SQLIO và cũng đảm bảo nếu bạn đang sử dụng các đĩa cơ mà phân vùng đĩa của bạn được căn chỉnh. Xem Thực tiễn tốt nhất về phân vùng đĩa của Microsoft .

  26. COLUMNSTORE INSERT/ UPDATEhiệu suất


2

Các lần đọc có thể là các ràng buộc & FK duy nhất đang được kiểm tra trong khi chèn - bạn có thể được cải thiện tốc độ nếu bạn có thể vô hiệu hóa / thả chúng trong quá trình chèn & bật / tạo lại chúng sau đó. Bạn sẽ cần phải kiểm tra nếu điều này làm cho nó chậm hơn so với việc giữ cho chúng hoạt động. Điều này cũng có thể không phải là một ý tưởng tốt nếu các quy trình khác được ghi vào cùng một bảng. - Ly Ly Gareth

Theo Q & A Khóa ngoại trở nên không đáng tin cậy sau khi chèn số lượng lớn , các ràng buộc FK trở nên không đáng tin cậy sau khi BULK INSERTkhông có CHECK_CONSTRAINTStùy chọn (trường hợp của tôi khi tôi kết thúc với các ràng buộc không đáng tin cậy). Không rõ ràng, nhưng sẽ không có ý nghĩa khi kiểm tra chúng và vẫn khiến chúng không đáng tin cậy. Tuy nhiên, PK và UNIQUE vẫn sẽ được kiểm tra (xem BULK INSERT (Transact-SQL) ). - Alexei

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.