2012-09-13 24 views
6

Tôi cần cải thiện hiệu suất tải dữ liệu. Chữ cái hiện tại tạo ra một lựa chọn đầy đủ từ một bảng:Làm cách nào để cải thiện hiệu suất chèn/cập nhật dữ liệu?

select Field1, Field2,...,FieldN from Table1 order by FieldM 

Dữ liệu mới được đọc từ một tệp văn bản (dòng văn bản). Bảng có khóa chính, chứa hai trường. Đối với mỗi dòng của một tệp văn bản, nó định vị hàng cần thiết bởi hai trường này (tức là khóa chính).

query.Locate('Field1;Field2',VarArrayOf([Value1,Value2]),[]); 

Nếu Locate lợi nhuận True, nó chỉnh sửa hàng, nếu không nó sẽ thêm một hình mới. Vì vậy, theo như bảng bao gồm khoảng 200.000 hàng, mỗi hoạt động Locate mất một lượng thời gian nhất định ... do đó, nó quản lý để cập nhật khoảng 5-6 hàng mỗi giây.

Tôi nên cân nhắc điều gì để cải thiện nó?

Có thể thay thế vị trí thông qua lựa chọn tuyệt vời này với các truy vấn riêng biệt?

Trả lời

10

KHÔNG sử dụng Định vị(). Nếu bạn sử dụng định vị() thì Delphi tìm kiếm hàng ở phía máy khách chỉ cần quét hàng được đặt từ truy vấn của bạn phải mất rất nhiều thời gian.

Nếu bạn có quyền truy cập MSSQL để tạo thủ tục lưu trữ, hãy tạo quy trình sau và chỉ chạy nó cho mỗi dòng từ tệp TEXT của bạn mà không có bất kỳ điều kiện nào (Sử dụng TAdoStoredProc.ExecProc trong Delphi). Vì vậy, trong trường hợp này, bạn không cần đầu tiên chọn và Xác định vị trí thủ tục. Nó cập nhật bản ghi nếu Filed1 và Field2 được tìm thấy và chèn nếu không.

CREATE PROCEDURE dbo.update_table1 
@Field1 int, --key1 
@Field2 int, --key2 
@Field3 int, -- data fileds 
@Field4 int 

AS 

SET NOCOUNT ON 
update table1 set [email protected],[email protected] 
     where [email protected] and [email protected]; 
IF(@@Rowcount=0) 
BEGIN 
    insert into table1(Field1,Field2,Field3,Field4) 
       values (@Field1,@Field2,@Field3,@Field4); 
END 
GO 

Đây là Delphi mã để gọi thủ tục lưu trữ này với ADO:

...... 
var 
    ADOStoredP: TADOStoredProc; 

    ...... 
begin 

........ 
    ADOStoredP:=TADOStoredProc.Create(nil); 
    try 
     ADOStoredP.Connection:=DataMod.SQL_ADOConnection; //Your ADO Connection instance here 
     ADOStoredP.ProcedureName:='Update_table1'; 
     ADOStoredP.Parameters.CreateParameter('@Field1', ftInteger, pdInput, 0, 0); 
     ADOStoredP.Parameters.CreateParameter('@Field2', ftInteger, pdInput, 0, 0); 
     ADOStoredP.Parameters.CreateParameter('@Field3', ftInteger, pdInput, 0, 0); 
     ADOStoredP.Parameters.CreateParameter('@Field4', ftInteger, pdInput, 0, 0); 

     While() -- Your text file loop here 
     begin 

     ADOStoredP.Parameters.ParamByName('@Field1').Value:=Field1 value from text file here; 
     ADOStoredP.Parameters.ParamByName('@Field2').Value:=Field2 value from text file here; 
     ADOStoredP.Parameters.ParamByName('@Field3').Value:=Field3 value from text file here; 
     ADOStoredP.Parameters.ParamByName('@Field4').Value:=Field4 value from text file here; 

     ADOStoredP.ExecProc; 

     end 

    finally 
     if Assigned(ADOStoredP) then 
     begin 
     ADOStoredP.Free; 
     end; 
    end; 

........ 
end; 
+3

Giải pháp này giảm thời gian tải từ 4 giờ xuống dưới 4 phút. Tôi thực sự đánh giá cao sự giúp đỡ của bạn! Cảm ơn bạn! – horgh

5
  1. Nếu có thể, bạn nên gửi tệp văn bản tới máy chủ đang chạy SQL Server. Sau đó, sử dụng OPENROWSET(BULK) để mở tệp văn bản (xem "E. Sử dụng nhà cung cấp BULK OPENROWSET với tệp định dạng để truy xuất các hàng từ tệp văn bản").
  2. Nếu bạn không thể gửi tệp văn bản tới máy chủ, hãy tạo bảng DB tạm thời hoặc liên tục và sử dụng INSERT để chèn tất cả các hàng tệp văn bản vào bảng.
  3. Nếu bạn đang sử dụng SQL Server 2008, thì bạn nên sử dụng toán tử MERGE. Nếu phiên bản SQL Server cũ hơn, thì bạn có thể sử dụng hai lệnh SQL: UPDATE và INSERT. Và như một nguồn dữ liệu sử dụng (1) OPENROWSET hoặc (2) DB bảng.
+0

Mặc dù nó là dễ dàng hơn để áp dụng các câu trả lời bằng Valex đến hoàn cảnh của tôi, cảm ơn bạn đã giúp đỡ. Máy chủ sql mục tiêu thậm chí là 2000. Một máy chủ khá cũ. Làm lại toàn bộ algorythm để tải các tập tin vào một số bảng tạm thời (và vv ..) không có giá trị bất kỳ đạt được hiệu suất (nếu có) so với những gì tôi đạt được (và bao nhiêu thời gian tôi đã dành cho nó) nhờ ý tưởng được đưa ra bởi valex . Dù sao cũng cảm ơn! – horgh

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