Cách tốt nhất để nhập lại lượng lớn dữ liệu với thời gian chết tối thiểu


11

Tôi cần nhập khoảng 500.000 bản ghi chứa dữ liệu tra cứu IP (chỉ đọc tham khảo) khoảng một lần một tuần (chỉ có ba cols / bigint cols).

Tôi thực sự không muốn lo lắng về việc hợp nhất dữ liệu với bảng hiện có, tôi muốn xóa dữ liệu cũ và nhập lại.

Các truy vấn lý tưởng chạy trên dữ liệu sẽ tiếp tục chạy (chúng tôi không nhận được nhiều trong số này và chúng có thể chấp nhận để chúng chạy chậm hơn một chút trong khi quá trình nhập xảy ra, nhưng cần phải hoạt động 24/7, vì vậy hãy chạy nó " hết giờ "không phải là một lựa chọn).

Những điều đã thử

SSIS: Tôi đã tạo một gói SSIS cắt ngắn bảng và nhập - mất khoảng 30 giây để chạy (thực sự quá lâu).

Bảng tạm thời: Nhập vào bảng tạm thời, cắt bớt và sao chép qua cũng mất khoảng 30 giây.

BCP: Nhập hàng loạt cũng khá chậm (vì một số lý do, nó chậm hơn SSIS (thậm chí không có chỉ số để duy trì) - Tôi đoán đó là việc cần làm với các giao dịch char-> int / bigint: /

Bàn gương? Vì vậy, hiện tại, tôi đang tự hỏi về việc đọc bảng thông qua chế độ xem, nhập dữ liệu vào bảng nhân bản và thay đổi chế độ xem để trỏ đến bảng này ... điều này có vẻ như sẽ nhanh chóng, nhưng có vẻ nhỏ bit hacky với tôi.

Đây có vẻ như là một vấn đề phổ biến, nhưng tôi không thể tìm thấy các thực tiễn được đề xuất - mọi ý tưởng sẽ được đánh giá cao nhất!

Cảm ơn

Câu trả lời:


13

Một giải pháp tôi đã sử dụng trước đây (và đã khuyến nghị ở đây và trên StackOverflow trước đó) là tạo hai lược đồ bổ sung:

CREATE SCHEMA shadow AUTHORIZATION dbo;
CREATE SCHEMA cache  AUTHORIZATION dbo;

Bây giờ hãy tạo một mô phỏng của bảng của bạn trong cachelược đồ:

CREATE TABLE cache.IPLookup(...columns...);

Bây giờ khi bạn đang thực hiện thao tác chuyển đổi của mình:

TRUNCATE TABLE cache.IPLookup;
BULK INSERT cache.IPLookup FROM ...;

-- the nice thing about the above is that it doesn't really
-- matter if it takes one minute or ten - you're not messing
-- with a table that anyone is using, so you aren't going to
-- interfere with active users.


-- this is a metadata operation so extremely fast - it will wait
-- for existing locks to be released, but won't block new locks
-- for very long at all:

BEGIN TRANSACTION;
  ALTER SCHEMA shadow TRANSFER    dbo.IPLookup;
  ALTER SCHEMA dbo    TRANSFER  cache.IPLookup;
COMMIT TRANSACTION;


-- now let's move the shadow table back over to
-- the cache schema so it's ready for next load:

ALTER SCHEMA cache TRANSFER shadow.IPLookup;
TRUNCATE TABLE cache.IPLookup; 

-- truncate is optional - I usually keep the data
-- around for debugging, but that's probably not
-- necessary in this case.

Điều này sẽ cồng kềnh hơn nếu bạn có khóa ngoại và các phụ thuộc khác (vì bạn có thể phải bỏ chúng và tạo lại chúng), và tất nhiên nó làm mất hiệu lực thống kê, v.v. và điều này, có thể ảnh hưởng đến các kế hoạch, nhưng nếu điều quan trọng nhất là có được dữ liệu chính xác trước người dùng của bạn với sự gián đoạn tối thiểu, đây có thể là một cách tiếp cận để xem xét.


Cảm ơn, một sự thay thế thú vị khác - Tôi nghĩ rằng hai câu lệnh cuối không hoàn toàn đúng, nên chuyển bóng vào bộ đệm và cắt bớt bộ đệm. Tôi tự hỏi nếu từ đồng nghĩa cũng có thể được sử dụng?
Đánh dấu

Bạn nói đúng, tôi đã nhầm lẫn. Tôi không chắc chính xác các từ đồng nghĩa sẽ tốt hơn như thế nào, tôi đoán đó cũng là một cách tiếp cận - có quan điểm chỉ ra từ đồng nghĩa và thay đổi từ đồng nghĩa cơ bản trong giao dịch khi bạn đã điền phiên bản khác. Cá nhân tôi thấy điều này tốt hơn một chút - khi bạn truy vấn dbo.IPLookup bạn biết đó là bảng "hiện tại" mà không cần phải theo đuổi chế độ xem và từ đồng nghĩa.
Aaron Bertrand

FYI Tôi đã viết blog về điều này chi tiết hơn trong tuần này: sqlperformance.com/2012/08/t-sql-queries/ gợi
Aaron Bertrand
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.