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

Thu hẹp các loại dữ liệu trên một bảng rất lớn

Trước hết, cảm ơn bạn đã làm điều này. Đó là một chiến thắng hiển nhiên mà nhiều người sẽ không thấy nhiều giá trị, nhưng nó sẽ rất xứng đáng :). Làm cho thế giới trở nên mát mẻ hơn bao giờ hết.

Về IsActive là một boolean. Tôi đoán là bạn đang nghĩ đến việc biến nó thành BIT đồng ruộng. Đó có thể là cách để đi, nhưng đôi khi tốt hơn là đi với TINYINT vì có khả năng mở rộng nghĩa thành nhiều hơn 2 trạng thái. Trong trường hợp đó, nó thực sự trở thành nhiều hơn của StatusID . Thông thường nó là trường hợp của một cái gì đó bắt đầu một cách đơn giản là Hoạt động / Không hoạt động , nhưng sau này có thể Đã xóa và / hoặc những người khác. Từ góc độ định cỡ, TINYINT luôn là 1 byte. Mặt khác, BIT là 1 byte cho tối đa 8 BIT lĩnh vực . Có nghĩa là, một BIT trường là 1 byte, 2 BIT các trường cũng là một byte, v.v. lên đến 8 BIT các trường được lưu trữ trong một byte duy nhất. Vì vậy, không tiết kiệm dung lượng khi chọn BIT qua TINYINT khi bảng chỉ có 1 BIT đồng ruộng. Chỉ là một cái gì đó để xem xét.

Làm một ALTER TABLE là một chút nhiều cho một bảng lớn, như bạn đã thấy. Một tùy chọn, mặc dù không phải là một lựa chọn tuyệt vời, là thêm một NOT NULL trường-- Number_1new - with a DEFAULT giá trị (điều này sẽ xảy ra ngay lập tức do mặc định, ít nhất là bắt đầu với SQL 2012) mà không có giá trị nào tự nhiên có (ví dụ:255), và sau đó di chuyển từ từ các giá trị, trong một vòng lặp, như trong:

UPDATE TOP (5000) tab
SET tab.Number_1new = tab.Number_1
FROM [table] tab
WHERE tab.Number_1new = 255;

Và khi điều đó được thực hiện thì hãy làm:

sp_rename 'table.Number_1', 'Number_1old', 'COLUMN';
sp_rename 'table.Number_1new', 'Number_1', 'COLUMN';

Tất nhiên, tốt nhất nên bọc nó trong một GIAO DỊCH và bọc nó trong một THỬ / MÈO. Khi mã liên quan đã được cập nhật và mọi thứ đã được kiểm tra và dữ liệu có vẻ tốt, thì bạn có thể bỏ Number_1old cột.

Tuy nhiên, cách tốt nhất mà tôi đã tìm ra là tạo một bảng mới, từ từ chuyển đổi dữ liệu, sau đó hoán đổi các bảng và mã cùng một lúc. Tôi đã trình bày chi tiết các bước trong bài viết trên SQL Server Central: Tái cấu trúc 100 triệu hàng (hoặc khác) Bảng tính bằng Giây. SRSLY! (yêu cầu đăng ký miễn phí). Đề phòng có vấn đề khi truy cập bài viết đó, đây là các bước cơ bản:

  1. Tạo một bảng mới với cấu trúc lý tưởng - [tableNew]. Nếu bạn đang sử dụng Phiên bản Doanh nghiệp, hãy cân nhắc bật tính năng nén ROW hoặc PAGE vì chúng đôi khi có thể hữu ích. Nhưng hãy thực hiện một số nghiên cứu trước vì có một số tình huống chúng có tác động tiêu cực. Có tài liệu về MSDN để giúp bạn tìm ra nó cũng như một số công cụ để giúp ước tính khoản tiết kiệm tiềm năng. Nhưng ngay cả khi bạn bật tính năng nén, tôi sẽ không thấy hành động đó thay thế dự án bạn đang thực hiện ở đây.
  2. Thêm trình kích hoạt AFTER UPDATE, DELETE trên [table] để đồng bộ hóa các thay đổi (nhưng không cần lo lắng về các hàng mới)
  3. Tạo một Công việc Tác nhân SQL để di chuyển hàng loạt các hàng bị thiếu. Thực hiện điều này trong một vòng lặp có INSERT INTO [tableNew] (Columns) SELECT TOP (n) Columns FROM [table] WHERE ?? ORDER BY ??
  4. Mệnh đề WHERE và ORDER BY phụ thuộc vào tình huống. Chúng nên được hướng tới việc sử dụng tốt nhất chỉ mục được phân nhóm. Nếu chỉ mục nhóm của bảng mới có cấu trúc giống với bảng cũ / hiện tại, thì khi bắt đầu mỗi vòng lặp, bạn có thể lấy MAX ([id]) từ [tableNew] và sử dụng nó để lấy bảng WHERE table.[id] > @MaxIdInTableNew ORDER BY table.[id] .
  5. Tạo bảng mới, kích hoạt trên bảng hiện tại và Công việc tác nhân SQL một tuần hoặc lâu hơn trước khi bạn cần thực hiện toàn bộ. Khung thời gian đó có thể thay đổi tùy theo tình hình của bạn, nhưng hãy đảm bảo dành cho mình nhiều thời gian. Sẽ tốt hơn rất nhiều nếu công việc hoàn thành việc di chuyển các hàng và chỉ có một vài dòng chảy vào một thời điểm thay vì chỉ có 100 nghìn bộ đầy đủ như dự kiến ​​bắt đầu phát hành.
  6. Nếu kế hoạch là di chuyển các bảng có liên quan khác (tham chiếu PK cho hai FK mà bạn muốn chuyển thành INT s), sau đó đặt các trường đó tại đây INT bây giờ và chỉ cần không thêm FK cho đến khi các bảng khác đó được chuyển sang có các trường INT làm PK của chúng. Bạn không muốn phải xây dựng lại bảng này chỉ để thực hiện thay đổi đó cho các trường FK.
  7. Trong thời gian giới hạn (tất nhiên là trong TRY / CATCH):
    1. BẮT ĐẦU TRẦN
    2. đếm hàng cuối cùng trên cả hai bảng để đảm bảo mọi thứ được chuyển qua (có thể muốn kiểm tra kỹ các hàng trước khi phát hành để đảm bảo rằng trình kích hoạt đã thực hiện cập nhật và xóa như mong đợi)
    3. đổi tên bảng hiện tại thành "cũ"
    4. đổi tên bảng "mới" để không có bảng "mới"
    5. bỏ công việc SQL Agent (hoặc ít nhất là vô hiệu hóa nó)
    6. đổi tên và các đối tượng phụ thuộc, chẳng hạn như các ràng buộc, v.v.
    7. CAM KẾ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ái nào tốt hơn:Đánh dấu / Tra cứu khóa hoặc Quét chỉ mục

  2. Nén một phân vùng cụ thể trong một bảng trong SQL Server (T-SQL)

  3. Cách chỉnh sửa tùy chọn máy chủ được liên kết bằng T-SQL

  4. Xuất bộ kết quả thủ tục đã lưu trữ sang Excel trong SSMS

  5. Thay đổi ngôn ngữ mặc định của đăng nhập trong SQL Server