Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Các cột thưa thớt trong SQL Server:Ảnh hưởng đến thời gian và không gian

SQL Server 2008 đã giới thiệu các cột thưa thớt như một phương pháp để giảm lưu trữ cho các giá trị null và cung cấp các lược đồ có thể mở rộng hơn. Sự cân bằng là có thêm chi phí khi bạn lưu trữ và truy xuất các giá trị không phải NULL. Tôi quan tâm đến việc hiểu chi phí để lưu trữ các giá trị không phải NULL, sau khi nói chuyện với một khách hàng đang sử dụng kiểu dữ liệu này trong môi trường dàn dựng. Họ đang tìm cách tối ưu hóa hiệu suất ghi và tôi tự hỏi liệu việc sử dụng các cột thưa thớt có ảnh hưởng gì không, vì phương pháp của họ yêu cầu phải chèn một hàng vào bảng, sau đó cập nhật hàng đó. Tôi đã tạo một ví dụ giả định cho bản trình diễn này, được giải thích bên dưới, để xác định xem đây có phải là một phương pháp luận tốt để họ sử dụng hay không.

Đánh giá nội bộ

Khi xem xét nhanh, hãy nhớ rằng khi bạn tạo cột cho bảng cho phép giá trị NULL, nếu đó là cột có độ dài cố định (ví dụ:INT), nó sẽ luôn sử dụng toàn bộ chiều rộng cột trên trang ngay cả khi cột đó VÔ GIÁ TRỊ. Nếu đó là cột có độ dài thay đổi (ví dụ:VARCHAR), nó sẽ tiêu tốn ít nhất hai byte trong mảng bù cột khi NULL, trừ khi các cột nằm sau cột được điền cuối cùng (xem bài đăng trên blog của Kimberly Thứ tự cột không quan trọng… nói chung , Nhưng nó phụ thuộc). Một cột thưa thớt không yêu cầu bất kỳ khoảng trống nào trên trang cho các giá trị NULL, cho dù đó là cột có độ dài cố định hay độ dài thay đổi và bất kể cột nào khác được điền trong bảng. Điều đáng tiếc là khi một cột thưa thớt được điền, nó sẽ chiếm nhiều hơn bốn (4) byte bộ nhớ so với một cột không thưa thớt. Ví dụ:

Loại cột Yêu cầu lưu trữ
cột BIGINT, không thưa thớt, có không giá trị 8 byte
cột BIGINT, không thưa thớt, một giá trị 8 byte
cột BIGINT, thưa, có không giá trị 0 byte
cột BIGINT, thưa, với một giá trị 12 byte

Do đó, điều cần thiết là phải xác nhận rằng lợi ích lưu trữ lớn hơn hiệu suất tiềm năng truy xuất - điều này có thể không đáng kể dựa trên sự cân bằng giữa các lần đọc và ghi so với dữ liệu. Mức tiết kiệm không gian ước tính cho các loại dữ liệu khác nhau được ghi lại trong liên kết Sách Trực tuyến được cung cấp ở trên.

Các tình huống thử nghiệm

Tôi đã thiết lập bốn kịch bản khác nhau để thử nghiệm, được mô tả bên dưới và mỗi bảng đều có cột ID (INT), cột Tên (VARCHAR (100)) và cột Loại (INT), và sau đó là 997 cột NULLABLE.

ID kiểm tra Mô tả bảng Hoạt động DML
1 997 cột kiểu dữ liệu INT, NULLABLE, không thưa thớt Chèn một hàng cùng một lúc, điền ID, Tên, Loại và mười (10) cột NULLABLE ngẫu nhiên
2 997 cột kiểu dữ liệu INT, NULLABLE, thưa thớt Chèn một hàng cùng một lúc, điền ID, Tên, Loại và mười (10) cột NULLABLE ngẫu nhiên
3 997 cột kiểu dữ liệu INT, NULLABLE, không thưa thớt Chèn từng hàng một, chỉ điền ID, Tên, Loại, sau đó cập nhật hàng, thêm giá trị cho mười (10) cột NULLABLE ngẫu nhiên
4 997 cột kiểu dữ liệu INT, NULLABLE, thưa thớt Chèn từng hàng một, chỉ điền ID, Tên, Loại, sau đó cập nhật hàng, thêm giá trị cho mười (10) cột NULLABLE ngẫu nhiên
5 997 cột của kiểu dữ liệu VARCHAR, NULLABLE, không thưa thớt Chèn một hàng cùng một lúc, điền ID, Tên, Loại và mười (10) cột NULLABLE ngẫu nhiên
6 997 cột của kiểu dữ liệu VARCHAR, NULLABLE, thưa thớt Chèn một hàng cùng một lúc, điền ID, Tên, Loại và mười (10) cột NULLABLE ngẫu nhiên
7 997 cột của kiểu dữ liệu VARCHAR, NULLABLE, không thưa thớt Chèn từng hàng một, chỉ điền ID, Tên, Loại, sau đó cập nhật hàng, thêm giá trị cho mười (10) cột NULLABLE ngẫu nhiên
8 997 cột của kiểu dữ liệu VARCHAR, NULLABLE, thưa thớt Chèn từng hàng một, chỉ điền ID, Tên, Loại, sau đó cập nhật hàng, thêm giá trị cho mười (10) cột NULLABLE ngẫu nhiên

Mỗi thử nghiệm được chạy hai lần với tập dữ liệu 10 triệu hàng. Các tập lệnh đính kèm có thể được sử dụng để lặp lại thử nghiệm và các bước thực hiện như sau cho mỗi thử nghiệm:

  • Tạo cơ sở dữ liệu mới với các tệp nhật ký và dữ liệu được định kích thước trước
  • Tạo bảng thích hợp
  • Thống kê chờ ảnh chụp nhanh và thống kê tệp
  • Ghi lại thời gian bắt đầu
  • Thực thi DML (một lần chèn hoặc một lần chèn và một lần cập nhật) cho 10 triệu hàng
  • Ghi lại thời gian dừng
  • Thống kê chờ ảnh chụp nhanh và thống kê tệp và ghi vào bảng ghi nhật ký trong cơ sở dữ liệu riêng biệt trên bộ lưu trữ riêng
  • Ảnh chụp nhanh dm_db_index_physical_stats
  • Bỏ cơ sở dữ liệu

Thử nghiệm được thực hiện trên Dell PowerEdge R720 với bộ nhớ 64GB và 12GB được phân bổ cho phiên bản SQL Server 2014 SP1 CU4. Ổ cứng SSD Fusion-IO được sử dụng để lưu trữ dữ liệu cho các tệp cơ sở dữ liệu.

Kết quả

Kết quả thử nghiệm được trình bày bên dưới cho từng tình huống thử nghiệm.

Thời lượng

Trong tất cả các trường hợp, mất ít thời gian hơn (trung bình 11,6 phút) để điền vào bảng khi các cột thưa thớt được sử dụng, ngay cả khi hàng được chèn lần đầu tiên, sau đó được cập nhật. Khi hàng được chèn lần đầu tiên, sau đó được cập nhật, quá trình chạy kiểm tra mất gần gấp đôi thời gian so với khi hàng được chèn, số lượng sửa đổi dữ liệu được thực hiện nhiều gấp đôi.

Thời lượng trung bình cho mỗi tình huống thử nghiệm

Thống kê Chờ
ID bài kiểm tra Phần trăm trung bình Chờ trung bình (giây)
1 16,47 0,0001
2 14,00 0,0001
3 16,65 0,0001
4 15,07 0,0001
5 12,80 0,0001
6 13,99 0,0001
7 14,85 0,0001
8 15.02 0,0001

Số liệu thống kê chờ đợi nhất quán cho tất cả các thử nghiệm và không thể đưa ra kết luận dựa trên dữ liệu này. Phần cứng đáp ứng đủ nhu cầu tài nguyên trong tất cả các trường hợp thử nghiệm.

Thống kê Tệp

IO (đọc và ghi) trung bình trên mỗi tệp cơ sở dữ liệu

Trong mọi trường hợp, các bài kiểm tra với các cột thưa thớt tạo ra ít IO hơn (đáng chú ý là số lần ghi) so với các cột không thưa thớt.

Số liệu thống kê vật lý của chỉ mục
Trường hợp thử nghiệm Số lượng hàng Tổng số trang (chỉ mục theo nhóm) Tổng dung lượng (GB) Dung lượng trung bình được sử dụng cho các trang lá trong CI (%) Kích thước bản ghi trung bình (byte)
1 10.000.000 10.037.312 76 51,70 4.184,49
2 10.000.000 301.429 2 98,51 237,50
3 10.000.000 10.037.312 76 51,70 4,184.50
4 10.000.000 460,960 3 64,41 237,50
5 10.000.000 1.823.083 13 90,31 1.326,08
6 10.000.000 324.162 2 98,40 255,28
7 10.000.000 3.161.224 24 52.09 1.326,39
8 10.000.000 503.592 3 63,33 255,28

Sự khác biệt đáng kể tồn tại trong việc sử dụng không gian giữa các loại bàn không thưa thớt và thưa thớt. Điều này đáng chú ý nhất khi xem xét các trường hợp thử nghiệm 1 và 3, trong đó kiểu dữ liệu có độ dài cố định được sử dụng (INT), so với các trường hợp thử nghiệm 5 và 7, trong đó kiểu dữ liệu có độ dài thay đổi được sử dụng (VARCHAR (255)). Các cột số nguyên tiêu thụ không gian đĩa ngay cả khi NULL. Các cột có độ dài thay đổi tiêu thụ ít dung lượng đĩa hơn, vì chỉ có hai byte được sử dụng trong mảng bù đắp cho các cột NULL và không có byte nào cho các cột NULL nằm sau cột được điền cuối cùng trong hàng.

Hơn nữa, quá trình chèn một hàng và sau đó cập nhật nó gây ra sự phân mảnh cho kiểm tra cột có độ dài thay đổi (trường hợp 7), so với việc chỉ chèn hàng (trường hợp 5). Kích thước bảng gần như tăng gấp đôi khi phần chèn được theo sau bởi bản cập nhật, do hiện tượng tách trang xảy ra khi cập nhật các hàng, khiến các trang đầy một nửa (so với đầy 90%).

Tóm tắt

Kết luận, chúng tôi thấy dung lượng ổ đĩa và IO giảm đáng kể khi các cột thưa thớt được sử dụng và chúng hoạt động tốt hơn một chút so với các cột không thưa thớt trong các bài kiểm tra sửa đổi dữ liệu đơn giản của chúng tôi (lưu ý rằng hiệu suất truy xuất cũng nên được xem xét; có lẽ là chủ đề của một đăng).

Các cột thưa thớt có một tình huống sử dụng rất cụ thể và điều quan trọng là phải kiểm tra dung lượng ổ đĩa được tiết kiệm, dựa trên kiểu dữ liệu cho cột và số cột thường sẽ được điền trong bảng. Trong ví dụ của chúng tôi, chúng tôi có 997 cột thưa thớt và chúng tôi chỉ điền 10 trong số đó. Tối đa, trong trường hợp kiểu dữ liệu được sử dụng là số nguyên, một hàng ở cấp độ lá của chỉ mục nhóm sẽ sử dụng 188 byte (4 byte cho ID, tối đa 100 byte cho Tên, 4 byte cho loại, sau đó 80 byte cho 10 cột). Khi 997 cột không thưa thớt, thì 4 byte được phân bổ cho mỗi cột, ngay cả khi NULL, vì vậy mỗi hàng có ít nhất 4.000 byte ở cấp độ lá. Trong kịch bản của chúng tôi, các cột thưa thớt là hoàn toàn có thể chấp nhận được. Nhưng nếu chúng tôi điền 500 cột thưa thớt trở lên với các giá trị cho một cột INT, thì khả năng tiết kiệm không gian sẽ bị mất và hiệu suất sửa đổi có thể không còn tốt hơn nữa.

Tùy thuộc vào loại dữ liệu cho các cột của bạn và số lượng cột dự kiến ​​sẽ được điền trong tổng số, bạn có thể muốn thực hiện thử nghiệm tương tự để đảm bảo rằng khi sử dụng các cột thưa thớt, hiệu suất và bộ nhớ chèn có thể so sánh hoặc tốt hơn so với khi sử dụng -sparse cột. Đối với trường hợp không phải tất cả các cột đều được điền, các cột thưa thớt chắc chắn đáng được xem xét.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Các tính năng mới của SQL Server 2019

  2. Cấp quyền truy cập người dùng msdb vào hồ sơ thư cơ sở dữ liệu trong SQL Server (T-SQL)

  3. Cài đặt Trình điều khiển JDBC của Microsoft SQL Server trong các công cụ Tích hợp dữ liệu Pentaho và Máy chủ BA

  4. Truy vấn trả về danh sách phân cấp các loại sự kiện kích hoạt trong SQL Server

  5. Cài đặt SQL Server 2017