ฉันมีตารางในฐานข้อมูลการผลิตที่มีขนาด 525 GB ซึ่งไม่ได้ใช้ 383 GB:
ฉันต้องการเรียกคืนพื้นที่บางส่วนนี้ แต่ก่อนที่จะยุ่งกับฐานข้อมูลการผลิตฉันกำลังทดสอบกลยุทธ์บางอย่างในตารางที่เหมือนกันในฐานข้อมูลทดสอบที่มีข้อมูลน้อยลง ตารางนี้มีปัญหาที่คล้ายกัน:
ข้อมูลบางอย่างเกี่ยวกับตาราง:
- ปัจจัยเติมถูกตั้งค่าเป็น 0
- มีประมาณ 30 คอลัมน์
- หนึ่งในคอลัมน์คือ LOB ของรูปภาพประเภทและมันจัดเก็บไฟล์ที่มีขนาดตั้งแต่ไม่กี่ KB ถึงหลายร้อย MB
- ตารางนี้ไม่มีดัชนีสมมุติฐานที่เกี่ยวข้อง
เซิร์ฟเวอร์กำลังเรียกใช้ SQL Server 2017 (RTM-GDR) (KB4505224) - 14.0.2027.2 (X64) ฐานข้อมูลใช้SIMPLE
โมเดลการกู้คืน
บางสิ่งที่ฉันได้ลอง:
ALTER INDEX ALL ON dbo.MyTable REBUILD
สร้างใหม่ดัชนี: สิ่งนี้มีผลกระทบเล็กน้อยALTER INDEX ALL ON dbo.MyTable REORGANIZE WITH(LOB_COMPACTION = ON)
จัดระเบียบดัชนี: สิ่งนี้มีผลกระทบเล็กน้อยคัดลอกคอลัมน์ LOB ไปยังอีกตารางหนึ่งทิ้งคอลัมน์สร้างคอลัมน์ขึ้นใหม่และคัดลอกข้อมูลกลับมา (ดังที่อธิบายไว้ในโพสต์นี้: การเพิ่มพื้นที่เซิร์ฟเวอร์ SQL ที่ไม่ได้ใช้พื้นที่ว่าง ) สิ่งนี้ลดพื้นที่ที่ไม่ได้ใช้ แต่ดูเหมือนว่าจะแปลงเป็นพื้นที่ใช้แล้ว:
ใช้ยูทิลิตี bcp เพื่อส่งออกตารางตัดและโหลดใหม่ (ดังที่อธิบายไว้ในโพสต์นี้: วิธีเพิ่มพื้นที่ว่างที่ไม่ได้ใช้สำหรับตาราง ) สิ่งนี้ยังช่วยลดพื้นที่ที่ไม่ได้ใช้และเพิ่มพื้นที่ใช้งานในระดับที่ใกล้เคียงกับภาพด้านบน
- แม้ว่าจะไม่แนะนำ แต่ฉันลองใช้คำสั่ง DBCC SHRINKFILE และ DBCC SHRINKDATABASE แต่พวกเขาไม่ได้มีผลกระทบกับพื้นที่ที่ไม่ได้ใช้
- การวิ่ง
DBCC CLEANTABLE('myDB', 'dbo.myTable')
ไม่ได้สร้างความแตกต่าง - ฉันได้ลองข้างต้นทั้งหมดแล้วในขณะที่ยังคงรักษาประเภทข้อมูลรูปภาพและข้อความและหลังจากเปลี่ยนประเภทข้อมูลเป็น varbinary (สูงสุด) และ varchar (สูงสุด)
- ฉันพยายามนำเข้าข้อมูลไปยังตารางใหม่ในฐานข้อมูลใหม่และนี่เป็นการแปลงพื้นที่ที่ไม่ได้ใช้เป็นพื้นที่ใช้แล้วเท่านั้น ฉันระบุรายละเอียดของความพยายามนี้ในโพสต์นี้
ฉันไม่ต้องการใช้ความพยายามเหล่านี้กับฐานข้อมูลการผลิตหากสิ่งเหล่านี้เป็นผลลัพธ์ที่ฉันคาดได้ดังนั้น:
- ทำไมพื้นที่ที่ไม่ได้ใช้เพิ่งถูกแปลงเป็นพื้นที่ที่ใช้หลังจากความพยายามเหล่านี้แล้ว ฉันรู้สึกว่าฉันไม่มีความเข้าใจที่ดีว่าเกิดอะไรขึ้นภายใต้ประทุน
- มีอะไรอีกบ้างที่ฉันสามารถทำได้เพื่อลดพื้นที่ที่ไม่ได้ใช้โดยไม่เพิ่มพื้นที่ใช้งานหรือไม่
แก้ไข: นี่คือรายงานการใช้ดิสก์และสคริปต์สำหรับตาราง:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MyTable](
[Column1] [int] NOT NULL,
[Column2] [int] NOT NULL,
[Column3] [int] NOT NULL,
[Column4] [bit] NOT NULL,
[Column5] [tinyint] NOT NULL,
[Column6] [datetime] NULL,
[Column7] [int] NOT NULL,
[Column8] [varchar](100) NULL,
[Column9] [varchar](256) NULL,
[Column10] [int] NULL,
[Column11] [image] NULL,
[Column12] [text] NULL,
[Column13] [varchar](100) NULL,
[Column14] [varchar](6) NULL,
[Column15] [int] NOT NULL,
[Column16] [bit] NOT NULL,
[Column17] [datetime] NULL,
[Column18] [varchar](50) NULL,
[Column19] [varchar](50) NULL,
[Column20] [varchar](60) NULL,
[Column21] [varchar](20) NULL,
[Column22] [varchar](120) NULL,
[Column23] [varchar](4) NULL,
[Column24] [varchar](75) NULL,
[Column25] [char](1) NULL,
[Column26] [varchar](50) NULL,
[Column27] [varchar](128) NULL,
[Column28] [varchar](50) NULL,
[Column29] [int] NULL,
[Column30] [text] NULL,
CONSTRAINT [PK] PRIMARY KEY CLUSTERED
(
[Column1] ASC,
[Column2] ASC,
[Column3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[MyTable] ADD CONSTRAINT [DF_Column4] DEFAULT (0) FOR [Column4]
GO
ALTER TABLE [dbo].[MyTable] ADD CONSTRAINT [DF_Column5] DEFAULT (0) FOR [Column5]
GO
ALTER TABLE [dbo].[MyTable] ADD CONSTRAINT [DF_Column15] DEFAULT (0) FOR [Column15]
GO
ALTER TABLE [dbo].[MyTable] ADD CONSTRAINT [DF_Column16] DEFAULT (0) FOR [Column16]
GO
นี่คือผลลัพธ์ของการดำเนินการคำสั่งในคำตอบของ Max Vernon:
╔════════════╦═══════════╦════════════╦═════════════════╦══════════════════════╦════════════════════╗
║ TotalBytes ║ FreeBytes ║ TotalPages ║ TotalEmptyPages ║ PageBytesFreePercent ║ UnusedPagesPercent ║
╠════════════╬═══════════╬════════════╬═════════════════╬══════════════════════╬════════════════════╣
║ 9014280192║ 8653594624║ 1100376║ 997178 ║ 95.998700 ║ 90.621500 ║
╚════════════╩═══════════╩════════════╩═════════════════╩══════════════════════╩════════════════════╝
╔═════════════╦═══════════════════╦════════════════════╗
║ ObjectName ║ ReservedPageCount ║ UsedPageCount ║
╠═════════════╬═══════════════════╬════════════════════╣
║ dbo.MyTable ║ 5109090 ║ 2850245 ║
╚═════════════╩═══════════════════╩════════════════════╝
UPDATE:
ฉันวิ่งตามดังต่อไปนี้ที่ Max Vernon แนะนำ:
DBCC UPDATEUSAGE (N'<database_name>', N'<table_name>');
และนี่คือผลลัพธ์:
DBCC UPDATEUSAGE: Usage counts updated for table 'MyTable' (index 'PK_MyTable', partition 1):
USED pages (LOB Data): changed from (568025) to (1019641) pages.
RSVD pages (LOB Data): changed from (1019761) to (1019763) pages.
นี่เป็นการปรับปรุงการใช้งานดิสก์สำหรับตาราง:
และการใช้งานดิสก์โดยรวม:
ดังนั้นดูเหมือนว่าปัญหาคือการใช้งานดิสก์ที่ติดตามโดย SQL Server กลายเป็นไม่ตรงกับการใช้งานจริงของดิสก์ ฉันจะพิจารณาปัญหานี้แก้ไขได้ แต่ฉันสนใจที่จะรู้ว่าทำไมสิ่งนี้จะเกิดขึ้นตั้งแต่แรก!
DBCC UPDATEUSAGE
การอัปเดตพื้นที่ที่ไม่ได้ใช้และจำนวนหน้าที่ไม่ได้ใช้ ดูเหมือนว่าการใช้งานดิสก์และข้อมูลหน้าเว็บที่รายงานโดย SQL Server นั้นขาดการซิงค์อย่างมาก - ฉันอัพเดตโพสต์ด้วยรายละเอียด ฉันอยากรู้ว่าเรื่องนี้จะเกิดขึ้นได้อย่างไรในตอนแรก แต่อย่างน้อยก็พบปัญหา ขอบคุณสำหรับความช่วยเหลือของคุณฉันขอขอบคุณจริงๆ!