Điều gì xảy ra trong quá trình chèn lớn vào trên một bảng với khóa tổng hợp?


8

Kiến thức SQL của tôi còn hạn chế, vì vậy các thuật ngữ tôi sẽ sử dụng rất có thể không phải là thuật ngữ phù hợp.

Tôi có một bảng sẽ lưu trữ kết quả kiểm tra, cho nhiều địa điểm.

Các bài kiểm tra sẽ được ghi lại trong các cơ sở dữ liệu khác nhau tại các địa điểm khác nhau (không có kết nối mạng) và vị trí "chính" sẽ thường xuyên "nhập" kết quả kiểm tra từ các vị trí khác.

Tôi dự định có một khóa chính tổng hợp được nhóm trên các cột LocationId (int) và Date (datetime), theo thứ tự đó. Lý do là nó sẽ giữ tất cả các kết quả cho một vị trí cùng nhau và tôi gần như sẽ không bao giờ thực hiện truy vấn theo phạm vi ngày, mà thay vào đó là theo phạm vi ngày và vị trí.

Kích thước hàng sẽ là 80 đến 100 byte và số lượng kết quả kiểm tra không được vượt quá vài triệu. Một "nhập" thông thường sẽ chèn 50 đến 100 nghìn kết quả từ một vị trí khác.

Điều gì sẽ xảy ra trong quá trình nhập khẩu? SQL sẽ "di chuyển" các hàng hiện có để duy trì phân cụm hay nó sẽ để bảng trở nên "bị phân mảnh"? Điều này có thể gây ra một hiệu suất lớn nếu việc nhập được thực hiện một hàng tại một thời điểm không? Tôi có nên chỉ không bận tâm đến việc sắp xếp các hàng và chỉ cần thêm một cột danh tính làm khóa chính và một chỉ mục trên cột Ngày để trợ giúp với các truy vấn của tôi?

Câu trả lời:


19

Chúa ơi, bạn đã có rất nhiều câu hỏi ở đây. Hãy phá vỡ điều này.

Hỏi: SQL sẽ "di chuyển" các hàng hiện có để duy trì phân cụm hay nó sẽ để bảng trở nên "bị phân mảnh"?

Hãy nghĩ về một cơ sở dữ liệu như một bộ sưu tập các trang - những mẩu giấy theo nghĩa đen được đặt trên bàn của bạn. Hãy nghĩ về từ điển bây giờ. Nếu bạn muốn thêm nhiều từ hơn vào từ điển, bạn có thể thêm chúng vào vị trí nếu các trang có không gian trống.

Khi bạn lần đầu tiên bắt đầu với một từ điển trống, điều này tương đối dễ dàng. Nhưng hãy nghĩ về một từ điển trưởng thành với hàng ngàn trang giấy trong đó, tất cả đều đầy đủ.

Khi bạn muốn thêm nhiều từ hơn vào từ điển trưởng thành đó, tỷ lệ cược sẽ không còn chỗ trống trên trang. SQL Server sẽ "xé" một trang - nó sẽ đưa một trang hoàn toàn mới vào một nơi khác và chuyển một số từ trên trang mới đó. Trang mới sẽ ở cuối từ điển. Tin tốt là ngay sau hành động đó, giờ đây có một trang trống một nửa ở cuối từ điển của bạn, và cả ở giữa, cả hai đều có khoảng trống để thêm từ.

Nếu bạn tình cờ thêm chúng theo thứ tự đó, đó là. (Đây là lý do tại sao cách bạn tải dữ liệu ngày càng trở nên quan trọng.)

Điều này có thể gây ra một hiệu suất lớn nếu việc nhập được thực hiện một hàng tại một thời điểm không?

Quên chỉ mục trong một giây - thêm dữ liệu một hàng tại một thời điểm chỉ là không hiệu quả bất kể cấu trúc lập chỉ mục. SQL Server là một hệ thống dựa trên tập hợp - bất cứ khi nào bạn có thể làm việc theo bộ, có lẽ bạn nên làm.

Điều gì xảy ra khi tôi truy vấn dữ liệu?

Bạn đã không hỏi điều này, nhưng tôi đang hỏi nó cho bạn, hahaha.

Nghĩ lại về hậu quả của việc chèn của chúng tôi. Bây giờ chúng tôi đã có một từ điển hầu hết được đặt hàng, nhưng khi bạn đến một vài điểm của từ điển, bạn sẽ phải nhảy ra phía sau để đọc từ một vài trang khác. Nếu tất cả các trang này được lưu trong bộ nhớ của bạn (RAM, vùng đệm, v.v.) thì chi phí sẽ không quá lớn. Hầu hết quyền truy cập bộ nhớ là ngẫu nhiên - không giống như SQL Server lưu trữ từ điển của bạn theo bộ nhớ theo thứ tự.

Mặt khác, nếu bạn cần tìm nạp dữ liệu từ các ổ cứng từ tính thông thường (quay gỉ), thì cuối cùng bạn có thể nhận được một chút lợi ích về hiệu suất nếu dữ liệu đó được lưu theo thứ tự. Tuy nhiên, mục tiêu thiết kế thực sự ở đây là lấy dữ liệu từ RAM thay vì lấy từ ổ đĩa. Sự khác biệt giữa dữ liệu phân mảnh trên đĩa so với dữ liệu bị phân mảnh trên đĩa không có gì đáng kể bằng sự khác biệt giữa lấy dữ liệu từ đĩa so với lấy từ RAM .

Tôi có nên không bận tâm đến việc sắp xếp các hàng và chỉ cần thêm một cột danh tính làm khóa chính và một chỉ mục trên cột Ngày để trợ giúp với các truy vấn của tôi?

Bingo: đây là sự khác biệt giữa thiết kế cơ sở dữ liệu vật lý và thiết kế cơ sở dữ liệu logic. Các lập trình viên phải lo lắng rất nhiều về thiết kế cơ sở dữ liệu vật lý ban đầu, nhưng miễn là cơ sở dữ liệu của bạn có kích thước 100 GB, bạn có thể sửa thiết kế logic trong bài, có thể nói. Đặt một trường nhận dạng trên đó cho người mới bắt đầu, cụm trên đó và sau khi được sống vài tháng, hãy xem lại thiết kế chỉ mục để tối đa hóa hiệu suất.

Bây giờ, đã nói rằng, một khi bạn có kinh nghiệm với kiểu ra quyết định này, thì bạn sẽ được trang bị tốt hơn cho các chỉ số dự đoán ngay từ đầu. Mặc dù vậy, tôi thậm chí không thường nghĩ nhiều đến thiết kế chỉ mục ban đầu. Người dùng dường như không bao giờ truy vấn dữ liệu theo cách tôi mong đợi.


1
Từng người một chèn là một câu hỏi lý thuyết. Có vẻ đáng ngờ đối với tôi, hiệu suất khôn ngoan, rằng "các hàng được lưu trữ vật lý trên đĩa theo cùng thứ tự với chỉ mục được nhóm" như bạn đọc ở hầu hết các nơi.
Sacha K

Tôi sẽ đi cho một cột danh tính. Dữ liệu sẽ được thêm vào "ở cuối" và tự nhiên được sắp xếp theo ngày. Cùng một ngày cho các địa điểm khác nhau sẽ không "gần nhau" nhưng điều đó hoàn toàn không quan trọng với tôi.
Sacha K
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.