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

Chèn hàng loạt SQL Server - Phần 2

Trong phần trước của bài viết này, chúng ta đã thảo luận về cách nhập tệp CSV vào SQL Server với sự trợ giúp của câu lệnh BULK INSERT. Chúng tôi đã thảo luận về phương pháp luận chính của quy trình chèn số lượng lớn và cũng như chi tiết về các tùy chọn BATCHSIZE và MAXERRORS trong các tình huống. Trong phần này, chúng ta sẽ xem xét một số tùy chọn khác (FIRE_TRIGGERS, CHECK_CONSTRAINTS và TABLOCK) của quy trình chèn hàng loạt trong các tình huống khác nhau.

Tình huống 1:Chúng tôi có thể bật trình kích hoạt trong bảng đích trong quá trình chèn hàng loạt không?

Theo mặc định, trong quá trình chèn hàng loạt, các trình kích hoạt chèn được chỉ định trong bảng đích sẽ không được kích hoạt, tuy nhiên, trong một số trường hợp, chúng tôi có thể muốn bật các trình kích hoạt này. Giải pháp cho vấn đề này là sử dụng tùy chọn FIRE_TRIGGERS trong các câu lệnh chèn hàng loạt. Tôi muốn thêm thông báo rằng tùy chọn này có thể ảnh hưởng và làm giảm hiệu suất hoạt động chèn hàng loạt vì trình kích hoạt / trình kích hoạt có thể thực hiện các hoạt động riêng biệt trong cơ sở dữ liệu. Trong mẫu sau, chúng tôi sẽ chứng minh điều này. Lúc đầu, chúng tôi sẽ không đặt tham số FIRE_TRIGGERS và quá trình chèn hàng loạt sẽ không kích hoạt trình kích hoạt chèn. Trong tập lệnh T-SQL sau, chúng tôi sẽ xác định một trình kích hoạt chèn cho bảng Bán hàng.

 DROP TABLE NẾU TẠO BẢNG Bán hàng còn tồn tại [dbo]. [Doanh số] ([Khu vực] [varchar] (50), [Quốc gia] [varchar] (50), [ItemType] [varchar] (50) NULL, [ SalesChannel] [varchar] (50) NULL, [OrderPosystem] [varchar] (50) NULL, [OrderDate] datetime, [OrderID] bigint NULL, [ShipDate] datetime, [UnitsSold] float, [UnitPrice] float, [UnitCost] float, [TotalRevenue] float, [TotalCost] float, [TotalProfit] float) DROP TABLE NẾU TỒN TẠI BẢNG SalesLogCREATE SalesLog (OrderIDLog bigint) GOCREATE TRIGGER OrderLogIns ON SalesFOR INSERTASBEGIN SET NOCOUNT ON INSERT INTO SalesLogSERT SalesBULK 'INSendGO Hồ sơ bán hàng.csv'WITH (FIRSTROW =2, FIELDTERMINATOR =',', ROWTERMINATOR ='\ n'); CHỌN Đếm (*) TỪ Đăng ký bán hàng 

Như bạn có thể thấy ở trên, trình kích hoạt chèn không kích hoạt bởi vì chúng tôi không đặt tùy chọn FIRE_TRIGGERS. Bây giờ, chúng tôi sẽ thêm tùy chọn FIRE_TRIGGERS vào câu lệnh chèn hàng loạt để tùy chọn này cho phép chèn trình kích hoạt cháy.

 BULK INSERT SalesFROM 'C:\ 1500000 Sales Records.csv'WITH (FIRSTROW =2, FIELDTERMINATOR =', ', ROWTERMINATOR =' \ n ', FIRE_TRIGGERS); Số lượng GOSELECT (*) là [NumberOfRowsinTriggerTable] FROM SalesLog 

Tình huống 2:Làm cách nào để kích hoạt ràng buộc kiểm tra trong quá trình chèn hàng loạt?

Kiểm tra các ràng buộc cho phép chúng tôi thực thi tính toàn vẹn của dữ liệu trong các bảng SQL Server. Mục đích của ràng buộc là để kiểm tra các giá trị được chèn, cập nhật hoặc xóa theo quy định về cú pháp của chúng. Chẳng hạn như, ràng buộc NOT NULL cung cấp rằng một cột đã chỉ định không thể được sửa đổi bằng giá trị NULL. Bây giờ, chúng ta sẽ tập trung vào các ràng buộc và tương tác chèn hàng loạt. Theo mặc định, trong quá trình chèn hàng loạt, mọi ràng buộc kiểm tra và khóa ngoại đều bị bỏ qua, nhưng tùy chọn này có một số ngoại lệ. Theo tài liệu của Microsoft “Các ràng buộc UNIQUE và PRIMARY KEY luôn được thực thi. Khi nhập vào cột ký tự mà ràng buộc NOT NULL được xác định, BULK INSERT sẽ chèn một chuỗi trống khi không có giá trị nào trong tệp văn bản. ” Trong tập lệnh T-SQL sau, chúng tôi sẽ thêm một ràng buộc kiểm tra vào cột OrderDate, cột này kiểm soát ngày đặt hàng lớn hơn 01.01.2016.

 DROP TABLE NẾU TẠO BẢNG Bán hàng còn tồn tại [dbo]. [Doanh số] ([Khu vực] [varchar] (50), [Quốc gia] [varchar] (50), [ItemType] [varchar] (50) NULL, [ SalesChannel] [varchar] (50) NULL, [OrderPosystem] [varchar] (50) NULL, [OrderDate] datetime, [OrderID] bigint NULL, [ShipDate] datetime, [UnitsSold] float, [UnitPrice] float, [UnitCost] float, [TotalRevenue] float, [TotalCost] float, [TotalProfit] float) BẢNG BÁO GIÁ [Doanh số] THÊM CONSTRAINT OrderDate_CheckCHECK (OrderDate> '20160101') CHÈN SỐ LƯỢNG LỚN SalesFROM 'C:\ 1500000 Bản ghi bán hàng.csv'WITH (FIRSTROW =2 , FIELDTERMINATOR =',', ROWTERMINATOR ='\ n'); GOSELECT COUNT (*) AS [UnChekedData] FROM Sales WHERE OrderDate <'20160101' 

Như bạn có thể thấy trong mẫu trên, quá trình chèn hàng loạt bỏ qua kiểm soát ràng buộc kiểm tra. Tuy nhiên, SQL Server cho biết ràng buộc kiểm tra là không đáng tin cậy.

 SELECT is_not_trusted, * FROM sys.check_constraints where name ='OrderDate_Check' 

Giá trị này chỉ ra rằng ai đó đã chèn hoặc cập nhật một số dữ liệu vào cột này bằng cách bỏ qua ràng buộc kiểm tra, đồng thời cột này có thể chứa dữ liệu không nhất quán với tham chiếu đến ràng buộc đó. Bây giờ, chúng tôi sẽ cố gắng thực hiện câu lệnh chèn hàng loạt với tùy chọn CHECK_CONSTRAINTS. Kết quả rất đơn giản, kiểm tra ràng buộc trả về lỗi do dữ liệu không đúng.

 CHÈN SỐ LƯỢNG LỚN SalesFROM 'C:\ 1500000 Hồ sơ Bán hàng.csv'WITH (FIRSTROW =2, FIELDTERMINATOR =', ', ROWTERMINATOR =' \ n '); 

Tình huống 3:Làm cách nào để tăng hiệu suất trong nhiều lần chèn hàng loạt vào một bảng đích?

Mục đích chính của cơ chế khóa trong SQL Server là bảo vệ và đảm bảo tính toàn vẹn của dữ liệu. Trong bài viết Khái niệm chính về khóa SQL Server, bạn có thể tìm thấy chi tiết về cơ chế khóa. Bây giờ, chúng ta sẽ tập trung vào chi tiết khóa quy trình chèn hàng loạt. Nếu bạn chạy câu lệnh chèn hàng loạt mà không có tùy chọn TABLELOCK, nó sẽ có được khóa các hàng hoặc bảng theo phân cấp khóa. Tuy nhiên, trong một số trường hợp, chúng tôi có thể muốn thực hiện nhiều quy trình chèn hàng loạt dựa trên một bảng đích, vì vậy chúng tôi có thể giảm thời gian hoạt động của chèn hàng loạt. Lúc đầu, chúng tôi sẽ thực hiện đồng thời hai câu lệnh chèn số lượng lớn và phân tích hành vi của cơ chế khóa. Chúng tôi sẽ mở hai cửa sổ truy vấn trong SQL Server Management Studio và chạy đồng thời các câu lệnh chèn hàng loạt sau.

 CHÈN SỐ LƯỢNG LỚN SalesFROM 'C:\ 1500000 Hồ sơ Bán hàng.csv'WITH (FIRSTROW =2, FIELDTERMINATOR =', ', ROWTERMINATOR =' \ n '); 

Khi chúng tôi thực hiện truy vấn dmv (Chế độ xem quản lý động) sau, truy vấn này giúp theo dõi trạng thái của quá trình chèn hàng loạt.

 SELECT session_id, command, status, last_wait_type, text FROM sys.dm_exec_requests áp dụng chéo sys.dm_exec_sql_text (sys.dm_exec_requests.sql_handle) trong đó văn bản như '% BULK INSERT Sales%' và session_idpre> 

Như bạn có thể thấy trong hình trên, phiên 61, trạng thái quá trình chèn hàng loạt bị tạm dừng do khóa. Nếu chúng tôi xác minh sự cố, phiên 59 sẽ khóa bảng đích chèn hàng loạt và phiên 61 chờ giải phóng khóa này để tiếp tục quá trình chèn hàng loạt. Bây giờ, chúng tôi sẽ thêm tùy chọn TABLOCK vào các câu lệnh chèn hàng loạt và thực thi các truy vấn.

Khi chúng tôi thực thi lại truy vấn giám sát dmv, chúng tôi không thể thấy bất kỳ quá trình chèn số lượng lớn bị treo nào vì SQL Server sử dụng một loại khóa đặc biệt được gọi là khóa cập nhật hàng loạt (BU). Loại khóa này cho phép xử lý đồng thời nhiều thao tác chèn hàng loạt trên cùng một bảng và tùy chọn này cũng làm giảm tổng thời gian của quá trình chèn hàng loạt.

Khi chúng tôi thực hiện truy vấn sau trong quá trình chèn hàng loạt, chúng tôi có thể theo dõi chi tiết khóa và loại khóa.

 CHỌN dm_tran_locks.request_session_id, dm_tran_locks.resource_database_id, DB_NAME (dm_tran_locks.resource_database_id) NHƯ dbname, TRƯỜNG HỢP KHI resource_type ='OBJECT' THEN OBJECT_NAME (dm_tran_locks. indexes.name AS index_name, dm_tran_locks.resource_type, dm_tran_locks.resource_description, dm_tran_locks.resource_associated_entity_id, dm_tran_locks.request_mode, dm_tran_locks.request_statusFROM sys.dm_tran_locksLEFT JOIN sys.partitions ON partitions.hobt_id =dm_tran_locks.resource_associated_entity_idLEFT JOIN sys.indexes ON indexes.OBJECT_ID =partitions .OBJECT_ID VÀ indexes.index_id =partition.index_idWHERE resource_associated_entity_id> 0 AND resource_database_id =DB_ID () 

Kết luận

Trong bài viết này, chúng tôi đã khám phá tất cả các chi tiết về hoạt động chèn hàng loạt trong SQL Server. Đặc biệt, chúng tôi đã đề cập đến lệnh BULK INSERT và các cài đặt và tùy chọn của nó, đồng thời chúng tôi cũng phân tích các tình huống khác nhau gần với các vấn đề trong cuộc sống thực.

Tài liệu tham khảo

CHÈN SỐ LƯỢNG LỚN (Transact-SQL)

Điều kiện tiên quyết để ghi nhật ký tối thiểu trong nhập hàng loạt

Kiểm soát hành vi khóa để nhập hàng loạt

Đọc thêm

Xuất dữ liệu sang tệp phẳng với Tiện ích BCP và Nhập dữ liệu với Chèn hàng loạt

Công cụ hữu ích:

dbForge Data Pump - phần bổ trợ SSMS để lấp đầy cơ sở dữ liệu SQL với dữ liệu nguồn bên ngoài và di chuyển dữ liệu giữa các hệ thống.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tại sao ép kiểu / chuyển đổi từ int trả về dấu hoa thị

  2. Điều gì đại diện cho một đôi trong máy chủ sql?

  3. Sử dụng đúng các giao dịch trong SQL Server

  4. LINQ to SQL Hãy bỏ qua nguyên nhân gây ra nhiều câu lệnh SQL

  5. Cấp quyền chọn trên dạng xem không phải bảng cơ sở khi bảng cơ sở nằm trong một cơ sở dữ liệu khác