2009-07-29 37 views
6

Tôi muốn chèn n bản ghi vào một bảng duy nhất. Có thể có nhiều người dùng đồng thời và họ có thể chèn/cập nhật/chọn dữ liệu từ bảng này. Cách tốt nhất để chèn vào bảng như vậy là 1000 bản ghi:Hiệu suất truy vấn chèn Sql

  1. Gửi một truy vấn sql đơn lẻ đến cơ sở dữ liệu với nhiều lần chèn. Điều này tiết kiệm máy chủ cho các cuộc gọi cơ sở dữ liệu, nhưng (tôi không chắc chắn) khóa bảng cho đến khi chèn xong và tất cả các truy vấn khác vào bảng này sẽ đợi.
  2. Chia 1000 bản ghi trong một số đoạn và gửi chúng trong nhiều truy vấn sql. Điều này cho phép các truy vấn khác được thực thi trên bảng, nhưng dành thời gian trên máy chủ cho các cuộc gọi cơ sở dữ liệu.

Điều này có phụ thuộc vào thứ gì đó hay có một cách duy nhất luôn là cách tối ưu? Điều này có phụ thuộc vào việc các giao dịch có được sử dụng hay không, trong khi chèn dữ liệu? Có cách nào khác tốt hơn để thực hiện chèn như vậy không?

Cơ sở dữ liệu tôi sử dụng là MS SQL, nhưng nó thú vị như thế nào nó hoạt động trong DB khác như Oracle.

Trả lời

6

Điều này hoàn toàn phụ thuộc vào những gì RDBMS bạn đang sử dụng.

Trong Oracle, viết không bao giờ chặn lần đọc, đó là lý do tại sao bạn có thể đặt tất cả dữ liệu của mình một cách an toàn cùng một lúc. Tuy nhiên, lưu ý rằng điều này sẽ làm giảm hiệu suất, vì các truy vấn đồng thời sẽ cần lấy dữ liệu ra khỏi không gian bảng UNDO sẽ yêu cầu thêm lần đọc.

Trong SQL Server viết làm đọc khối trên hàng/trang bị ảnh hưởng (tùy thuộc vào vấn đề leo thang khóa), trừ khi bạn đặt TRANSACTION ISOLATION LEVEL thành SNAPSHOT.

Trong tất cả các công cụ giao dịch cho phép viết và đọc đồng thời, công cụ cần lưu trữ cả dữ liệu cũ và mới ở nơi nào đó để có sẵn cùng một lúc.

Trong Oracle, dữ liệu cũ được sao chép vào không gian bảng UNDO.

Trong SQL Server, bản sao được sao chép vào tempdb (chỉ khi bật chế độ cách ly SNAPSHOT, nếu không nó sẽ bị khóa).

Điều này luôn yêu cầu một số tài nguyên (bộ nhớ hoặc đĩa) và bạn có thể hết tài nguyên này nếu truy vấn UPDATE của bạn ảnh hưởng đến nhiều hàng.

1

Đặt mức độ cách ly (đồng thời) cho phép đọc dữ liệu cũ trong một giao dịch - ví dụ: SQL Server 2005+ có READ SNAPSHOT.

2

Tôi đã viết blog về điều này a while ago - Tôi nghĩ bài đăng trả lời một số câu hỏi của bạn. Lời khuyên của CK là âm thanh (và như vậy là Quassnoi - anh ấy có một số điểm tốt về Oracle) nếu bạn lo lắng về việc người đọc chặn các nhà văn.

+0

bài đăng blog thú vị +1. Nó khơi gợi sự quan tâm của tôi đối với các giao dịch _reason_ xuất hiện nhanh hơn trong thử nghiệm của bạn. Tôi nghi ngờ đó là bởi vì nhiều khóa cần thiết đã được thực hiện bằng cách vượt qua trước. Tuy nhiên, điều quan trọng nhất là bài đăng của bạn không giải quyết được hành vi đang tải. Các thử nghiệm của bạn dường như bị cô lập; trong một hệ thống sống tôi nghi ngờ kết quả sẽ đảo ngược khá nhanh chóng. – EBarr

2

Quy tắc chung là bạn nên để cơ sở dữ liệu tìm ra cách thực hiện công việc. Điều đó hoạt động tốt hơn bạn càng nói với nó trong một tuyên bố, tức là bạn nên chèn 1000 bản ghi trong một lần. Điều này sẽ làm việc tốt nhất cho hầu hết các máy chủ cơ sở dữ liệu và hầu hết các máy chủ không chặn đọc để viết.

Có ngoại lệ: nếu chèn chậm vì máy chủ chậm hoặc bảng lớn hoặc phức tạp, có thể tốt hơn là chia truy vấn thành các nhóm chèn nhỏ.

Phương pháp ở giữa sẽ là gửi nhiều lệnh chèn để nói 10 hoặc 100 hàng với các cam kết ở giữa trong một tập lệnh lớn với máy chủ.

Đã thêm: Hầu hết các máy chủ cơ sở dữ liệu không chặn đọc như trong Oracle, IBM DB/2 và MySQl sử dụng bảng InnoDB. SQL Server mặt khác quản lý để khóa các bảng ngay cả đối với lần đọc và không nằm trong số đó.

+1

Tôi nghĩ bạn sẽ tìm thấy hầu hết các DB có vấn đề mà người đọc chặn các nhà văn (Oracle không). – RichardOD

+0

Tham chiếu lõi của Microsoft ADO.NET đề xuất sử dụng kích thước lô từ 100 đến 1000. – RichardOD

+0

@RichardOD: Bạn có thể đăng liên kết tới đề xuất này không? – Kamarey

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