2012-06-19 34 views
15

Công ty của tôi bị nguyền rủa bởi quan hệ đối tác cộng sinh chuyển thành ký sinh trùng. Để lấy dữ liệu của chúng tôi từ ký sinh trùng, chúng tôi phải sử dụng kết nối odbc chậm chạp. Tôi đã thông báo gần đây mặc dù tôi có thể nhận được thông lượng nhiều hơn bằng cách chạy các truy vấn song song (ngay cả trên cùng một bảng).Cách nhanh nhất để chèn song song với một bảng duy nhất

Có một bảng đặc biệt lớn mà tôi muốn trích xuất dữ liệu và chuyển nó vào bảng cục bộ của chúng tôi. Chạy truy vấn song song tôi có thể nhận dữ liệu nhanh hơn, nhưng tôi cũng tưởng tượng rằng điều này có thể gây ra vấn đề với việc cố gắng ghi dữ liệu từ nhiều truy vấn vào cùng một bảng cùng một lúc.

Bạn có thể đưa ra lời khuyên nào về cách xử lý tốt nhất tình huống này để tôi có thể tận dụng tối đa tốc độ sử dụng truy vấn song song?

EDIT: Tôi đã nhận được một số phản hồi tuyệt vời ở đây, nhưng tôi nghĩ rằng tôi không hoàn toàn rõ ràng về thực tế là tôi đang kéo dữ liệu qua máy chủ được liên kết (sử dụng trình điều khiển odbc). Nói cách khác có nghĩa là tôi có thể chạy các câu lệnh INSERT bình thường và tôi tin rằng sẽ cung cấp hiệu suất tốt hơn SqlBulkCopy hoặc INSUL BULK (thực ra, tôi không tin rằng INSUL BULK thậm chí sẽ là một lựa chọn).

+0

Như bạn đã đề xuất, viết song song có thể sẽ không giúp hiệu suất. Bạn có thể tìm thấy một số câu trả lời ở đây http://stackoverflow.com/questions/2861944/how-do-i-do-very-fast-inserts-to-sql-server-2008 –

+0

Bạn có đang di chuyển dữ liệu không? Tôi hỏi vì bạn đã nói dữ liệu di chuyển của bạn đến các bảng cục bộ. Ngoài ra làm thế nào bạn làm điều này trong mã ví dụ như C# hoặc là một phần của một công việc sql? –

+0

@mouters Có, nhưng dữ liệu mới không đi vào cơ sở dữ liệu của chúng tôi vì vậy tôi sẽ phải sao chép mọi thứ mới trên cơ sở hàng ngày. Cho đến nay tôi đã làm nó trong ssms bằng tay nhưng ý tưởng song song sẽ được thực hiện trong C# nếu tôi làm điều đó. Có lẽ sẽ không làm điều này một song song b/c Tôi đã nhận tất cả các dữ liệu lịch sử bây giờ và thực sự chỉ cần thiết lập một công việc sql để chạy và nhận được dữ liệu mới hàng đêm. Nhưng tôi chỉ muốn nhận được một số thông tin về ý tưởng b/c tôi có thể đã sử dụng cho nó trong tương lai gần trên các công cụ khác. –

Trả lời

12

Bạn đã đọc Load 1TB in less than 1 hour chưa?

  1. Chạy nhiều quá trình tải khi bạn có CPU. Nếu bạn có 32 CPU, hãy chạy 32 tải song song. Nếu bạn có 8 CPU, hãy chạy 8 tải song song .
  2. Nếu bạn có quyền kiểm soát việc tạo tệp đầu vào của mình, hãy đặt chúng có kích thước đồng đều chia cho số lượng chuỗi tải bạn muốn chạy song song. Đồng thời đảm bảo tất cả các bản ghi thuộc về một phân vùng nếu bạn muốn sử dụng chiến lược phân vùng chuyển đổi.
  3. Sử dụng chèn BULK thay vì BCP nếu bạn đang chạy quá trình trên máy chủ SQL .
  4. Sử dụng phân vùng bảng để đạt được 8-10% khác, nhưng chỉ khi các tệp nhập của bạn được đảm bảo để phù hợp với chức năng phân vùng của bạn, nghĩa là tất cả các bản ghi trong một tệp phải nằm trong cùng một phân vùng.
  5. Sử dụng TABLOCK để tránh hàng tại một thời điểm khóa.
  6. Sử dụng ROWS PER BATCH = 2500 hoặc một cái gì đó gần đây nếu bạn đang nhập nhiều luồng vào một bảng.

Đối với SQL Server 2008, có một số trường hợp bạn có thể sử dụng minimal logging for a standard INSERT SELECT:

SQL Server 2008 giúp tăng cường các phương pháp mà nó có thể xử lý với tối thiểu khai thác gỗ. Nó hỗ trợ các câu lệnh INSERT SELECT thường xuyên ghi lại. Ngoài ra, bật cờ theo dõi 610 cho phép SQL Server 2008 hỗ trợ ghi nhật ký tối thiểu đối với một cây B không trống cho khóa mới phạm vi gây ra phân bổ trang mới.

+0

Cảm ơn, điều này là tốt nhưng thực sự không áp dụng (ngoài # 1) cho tình huống của tôi vì tôi không tải dữ liệu từ tệp nhưng từ máy chủ được liên kết qua trình điều khiển odbc ... vì vậy tôi thường xuyên đặt câu lệnh chèn dù sao. Vì vậy, tôi tự hỏi làm thế nào tôi sẽ đi về làm tương đương với thiết lập ROWS PER BATCH trên một tuyên bố chèn bình thường hoặc nếu tôi có thể? –

+0

Bạn đang sử dụng SQL Server 2008 trở lên? Ghi lại tối thiểu các câu lệnh INSERT SELECT chuẩn được hỗ trợ trong một số trường hợp nhất định. – 8kb

3

Nếu bạn muốn thực hiện điều này trong mã tức là C# có tùy chọn sử dụng SqlBulkCopy (trong không gian tên System.Data.SqlClient) và như bài viết này có thể làm điều này song song.

http://www.adathedev.co.uk/2011/01/sqlbulkcopy-to-sql-server-in-parallel.html

+0

Chỉ có điều xấu về làm bất cứ điều gì số lượng lớn là bạn sẽ phải xây dựng lại bạn chỉ số sau đó kể từ khi nó bỏ qua chúng trên chèn. – SQLMason

+0

Vâng, tôi đã chỉ nghĩ đến việc sử dụng C# để quản lý sự song song. Tôi không nghĩ rằng bằng cách sử dụng SqlBulkCopy sẽ được bất kỳ nhanh hơn bằng cách sử dụng SqlCommand.ExecuteNonQuery() để phát hành cùng một thiết lập dựa trên tuyên bố chèn tôi sẽ làm trực tiếp từ SSMS, phải không? Tôi nghĩ một điều mà mọi người trả lời cứ quên là điều này không đến từ một tệp phẳng ... Tôi có quyền truy cập để chạy câu lệnh chèn thông thường trực tiếp trên dữ liệu nguồn. –

+0

Tôi đoán khi bạn nói điều này "cùng một tuyên bố chèn dựa trên bộ" bạn có nghĩa là bạn có thể làm một cơ sở dữ liệu chéo tham gia? Ngoài ra, bạn cũng đang cố chèn vào nguồn, hay bạn chỉ có nghĩa là bạn có quyền truy cập đọc/ghi vào cơ sở dữ liệu nguồn (nhưng về cơ bản không liên quan đến những gì bạn đang cố gắng làm ở đây)? –