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

Làm việc xung quanh giới hạn cột tối đa của SQL Server là 1024 và kích thước bản ghi 8kb

Điều này đơn giản là không thể. Xem Bên trong Công cụ lưu trữ:Giải phẫu hồ sơ

Giả sử bảng của bạn giống như thế này.

CREATE TABLE T1(
    col_1 varchar(8000) NULL,
    col_2 varchar(8000) NULL,
    /*....*/
    col_999 varchar(8000) NULL,
    col_1000 varchar(8000) NULL
) 

Sau đó, ngay cả một hàng có tất cả NULL các giá trị sẽ sử dụng bộ nhớ sau.

  • Các bit trạng thái 1 byte A
  • Các bit trạng thái 1 byte B
  • Độ lệch số lượng cột 2 byte
  • 125 byte NULL_BITMAP (1 bit mỗi cột cho 1.000 cột)

Vì vậy, đó là 129 byte được đảm bảo đã được sử dụng hết (còn lại 7.931).

Nếu bất kỳ cột nào có giá trị không phải là NULL hoặc một chuỗi trống thì bạn cũng cần không gian cho

  • Số lượng cột có độ dài thay đổi 2 byte (còn lại 7,929).
  • Bất kỳ nơi nào trong khoảng từ 2 - 2000 byte đối với mảng bù cột.
  • Bản thân dữ liệu.

Mảng bù cột sử dụng 2 byte cho mỗi cột có độ dài thay đổi ngoại trừ nếu cột đó và tất cả các cột sau đó cũng có độ dài bằng không. Vì vậy, cập nhật col_1000 sẽ buộc toàn bộ 2000 byte được sử dụng trong khi cập nhật col_1 sẽ chỉ sử dụng 2 byte.

Vì vậy, bạn có thể điền vào mỗi cột 5 byte dữ liệu và khi tính đến 2 byte mỗi cột trong mảng bù cột sẽ cộng tới 7.000 byte nằm trong 7.929 còn lại.

Tuy nhiên, dữ liệu bạn đang lưu trữ là 102 byte (51 nvarchar ký tự) để điều này có thể được lưu trữ ngoài hàng với con trỏ 24 byte đến dữ liệu thực tế còn lại trong hàng.

FLOOR(7929/(24 + 2)) = 304

Vì vậy, trường hợp tốt nhất sẽ là bạn có thể lưu trữ 304 cột dữ liệu độ dài này và đó là nếu bạn đang cập nhật từ col_1 , col_2 , ... . Nếu col_1000 chứa dữ liệu thì phép tính là

FLOOR(5929/24) = 247

Đối với NTEXT cách tính tương tự ngoại trừ nó có thể sử dụng con trỏ 16 byte điều này sẽ cho phép bạn đưa dữ liệu vào một vài cột bổ sung

FLOOR(7929/(16 + 2)) = 440

Sự cần thiết phải tuân theo tất cả các con trỏ hàng tắt này cho bất kỳ SELECT nào chống lại bảng có thể sẽ rất bất lợi cho hiệu suất.

Tập lệnh để kiểm tra điều này

DROP TABLE T1

/* Create table with 1000 columns*/
DECLARE @CreateTableScript nvarchar(max) = 'CREATE TABLE T1('

SELECT @CreateTableScript += 'col_' + LTRIM(number) + ' VARCHAR(8000),'
FROM master..spt_values
WHERE type='P' AND number BETWEEN 1 AND 1000
ORDER BY number

SELECT @CreateTableScript += ')'

EXEC(@CreateTableScript)

/* Insert single row with all NULL*/
INSERT INTO T1 DEFAULT VALUES


/*Updating first 304 cols succeed. Change to 305 and it fails*/
DECLARE @UpdateTableScript nvarchar(max) = 'UPDATE T1 SET  '

SELECT @UpdateTableScript += 'col_' + LTRIM(number) + ' = REPLICATE(1,1000),'
FROM master..spt_values
WHERE type='P' AND number BETWEEN 1 AND 304
ORDER BY number

SET @UpdateTableScript = LEFT(@UpdateTableScript,LEN(@UpdateTableScript)-1)
EXEC(@UpdateTableScript)


  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ập nhật thống kê SQL Server bằng cách sử dụng kế hoạch bảo trì cơ sở dữ liệu

  2. SQL Server - Các ký tự không hợp lệ trong tên tham số

  3. VỚI CHECK ADD CONSTRAINT, sau đó là CHECK CONSTRAINT so với ADD CONSTRAINT

  4. Tăng nhận dạng cột SQL Server 2012 nhảy từ 6 lên 1000+ ở mục nhập thứ 7

  5. Làm cách nào để tạo người dùng trong SQL-Server chỉ có quyền truy cập vào một bảng và chỉ có thể chèn các hàng