การเพิ่มตารางเซิร์ฟเวอร์ SQL ที่ไม่ได้ใช้พื้นที่


11

ฉันมีตารางใน SQL Server 2012 Express พร้อมพื้นที่ที่ไม่ได้ใช้จำนวนมาก

ฉันต้องการพื้นที่ว่างในฐานข้อมูล

| NAME | ROWS | สงวนลิขสิทธิ์ DATA | INDEX_SIZE | ไม่ใช้
| ------------- | -------- | -------------- | ----------- --- | ------------ | -------------- |
| MyTableName | 158890 | 8928296 KB | 5760944 KB | 2248 KB | 3165104 KB |

ฉันจะให้ SQL เปิดตัว 3165104KB ได้อย่างไร

ฉันได้ลองแล้ว:

Alter table MyTableName Rebuild
DBCC CLEANTABLE (MyDbName,"MyTableName ", 0)
ALTER INDEX ALL ON MyTableName REORGANIZE ; 
ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF) 

นี่คือตาราง:

CREATE TABLE [dbo].[MyTableName](
    [ImageID] [int] IDENTITY(1,1) NOT NULL,
    [DateScan] [datetime] NULL,
    [ScanImage] [image] NULL,
 CONSTRAINT [PK_Image] PRIMARY KEY CLUSTERED 
(
    [ImageID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

สิ่งเดียวที่เราทำคือแทนที่ScanImageในทุกแถวด้วยภาพที่เล็กกว่า (นี่คือพื้นที่ที่ไม่ได้ใช้งานมากมี)

คำตอบ:


10

สิ่งเดียวที่เราทำคือแทนที่ScanImageในทุกแถวด้วยภาพที่เล็กกว่ามาก (นี่คือพื้นที่ที่ไม่ได้ใช้มีมาก)

จากการทำการทดลองบางวิธีวิธีที่มีประสิทธิภาพที่สุดในพื้นที่คือการปล่อยหน่วยการจัดสรรและ repopulate มันใหม่ (ถ้าคุณมีหน้าต่างการบำรุงรักษาเพื่อทำสิ่งนี้)

โค้ดตัวอย่างที่ทำให้การลดพื้นที่ดีที่สุดสำหรับฉันด้วยโครงสร้างตารางในคำถามคือ:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET XACT_ABORT ON;

BEGIN TRAN

SELECT [ImageID],
       [ScanImage]
INTO   #Temp
FROM   [dbo].[MyTableName]

ALTER TABLE [dbo].[MyTableName]
  DROP COLUMN [ScanImage]

/*Allocation unit not removed until after this*/
ALTER INDEX PK_Image ON MyTableName REBUILD

ALTER TABLE [dbo].[MyTableName]
  ADD [ScanImage] IMAGE NULL

UPDATE [dbo].[MyTableName]
SET    [ScanImage] = T.[ScanImage]
FROM   [dbo].[MyTableName] M
       JOIN #Temp T
         ON M.ImageID = T.[ImageID]

DROP TABLE #Temp

COMMIT 

ทุกอย่างอยู่ในธุรกรรมดังนั้นหากเครื่องขัดข้องเครื่องจะถูกย้อนกลับ SET XACT_ABORT ONอาจจะทำอย่างไรกับการจัดการข้อผิดพลาดบางอย่างหรืออย่างน้อย ฉันใช้SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;เพื่อป้องกันการแก้ไขใด ๆ ที่เกิดขึ้นพร้อมกันระหว่างหรือหลังจากการคัดลอกและการสูญหาย

จำนวนหน้า LOB ที่จองไว้หลังจากลดขนาดของimageในแถวทั้งหมดมีดังนี้:

+ ------------------------------------------------- - + --------------------- + + -------------------------
| กิจกรรม | lob_used_page_count | lob_reserved_page_count |
+ ------------------------------------------------- - + --------------------- + + -------------------------
| แทรก 10,000 แถวพร้อมข้อมูล 100,000 ไบต์ในแต่ละ | 135005 | 135017 |
| อัปเดตแถวทั้งหมดเป็นข้อมูลรูปภาพขนาด 10,000 ไบต์ | 31251 | 135012 |
| จัดระเบียบใหม่ 23687 | 25629 |
| ปล่อยและเพิ่มข้อมูลรูปภาพอีกครั้ง | 13485 | 13489 |
+ ------------------------------------------------- - + --------------------- + + -------------------------

1
หรือถ้าตารางมีขนาดใหญ่ให้ BCP ออกข้อมูลจากนั้นใส่ BULK INSERT กลับเข้า - ในระหว่างหน้าต่างการบำรุงรักษา
Kin Shah

6

ลอง

ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF)

สิ่งนี้จะสร้างดัชนีคลัสเตอร์ขึ้นใหม่ดังนั้นคุณจะต้องมีห้องเพิ่มเติมในฐานข้อมูลของคุณเพื่อให้การดำเนินการเสร็จสมบูรณ์ หากคุณไม่มีพื้นที่เพิ่มเติมเนื่องจากดิสก์ของคุณเต็มคุณอาจเพิ่มไฟล์ข้อมูลใหม่ลงในฐานข้อมูล (บนดิสก์อื่น) และย้ายตารางไปที่

นอกจากนี้ยังเป็นไปได้ที่ดัชนีคลัสเตอร์จะถูกกำหนดด้วย FILLFACTOR น้อยกว่า 100% หากตั้งค่าตัวประกอบการเติมไว้ที่ 66% จะเหลือ 1/3 ของหน้าข้อมูลว่างเปล่าเพื่อใช้ในอนาคต หากนี่คือปัญหาที่คุณสามารถแก้ไขปัจจัยการเติมโดยใช้ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF, FILLFACTOR=100)

หากคุณเพิ่งลดความยาวของตัวแปรฟิลด์จากตารางคุณสามารถลอง DBCC CLEANTABLE( Databasename, "MyTableName")

หนังสือออนไลน์ (BOL) มีบทความที่ยอดเยี่ยมเกี่ยวกับการสร้างดัชนีใหม่ที่http://technet.microsoft.com/en-us/library/ms188388%28v=sql.100%29.aspx


2

SIMPLEตรวจสอบให้แน่ใจโหมดการกู้คืนฐานข้อมูลเป็น

VARBINARY(MAX)เปลี่ยนคอลัมน์เป็น

จากนั้นลองคัดลอกข้อมูลลงในตารางใหม่โดยสมบูรณ์

sp_spaceused "tablename"ตรวจสอบขนาดโต๊ะใหม่โดยใช้ หากคุณพอใจกับพื้นที่ที่ไม่ได้ใช้ของตารางให้ตรวจสอบพื้นที่ที่ไม่ได้ใช้ของฐานข้อมูลโดยใช้คำสั่งเดียวกันโดยไม่ระบุชื่อตาราง พื้นที่ดังกล่าวยังคงอยู่ในไฟล์ฐานข้อมูลและไม่ได้เผยแพร่สู่ระบบปฏิบัติการ

คุณสามารถวางตารางเดิมและเปลี่ยนชื่อตารางใหม่หรือทำสิ่งเดียวกันอีกครั้งและใช้ชื่อตารางเดิมหากคุณไม่เชื่อถือการดำเนินการเปลี่ยนชื่อ (ฉันไม่เชื่อถืออย่างสมบูรณ์)

หากวิธีนี้ใช้ได้ผลขั้นตอนสุดท้ายนั้นง่าย: คุณรู้วิธีย่อขนาดไฟล์และปล่อยพื้นที่ที่ไม่ได้ใช้

หากมีคีย์ต่างประเทศบันทึกคำจำกัดความของพวกเขาวางพวกเขาปฏิบัติงานที่ฉันพูดถึงข้างต้นและสร้างคีย์ต่างประเทศใหม่ในภายหลัง ของหลักสูตรนี้จะใช้เวลาและการดำเนินการนี้ควรทำในช่วงปิด งานทั้งหมดนี้สามารถทำได้ผ่านสคริปต์และปล่อยให้มันทำงานข้ามคืน


1

ฉันจะสร้างฐานข้อมูลใหม่และคัดลอกข้อมูลไปยังมัน คุณควรใช้ตัวช่วยสร้างการนำเข้า / ส่งออก (เห็นได้ชัดว่าการสำรองข้อมูลและเรียกคืนจะทำให้เกิดปัญหา) ตรวจสอบผลลัพธ์ของการนำเข้าข้อมูล หากทุกอย่างดูดีเปลี่ยนชื่อฐานข้อมูลเดิมแล้วเปลี่ยนชื่อฐานข้อมูลใหม่เป็นชื่อที่คุณต้องการใช้ (ฉันมักจะรอสักครู่ก่อนที่จะวางต้นฉบับเพียงเพื่อให้ตรวจสอบออนไลน์อีกครั้ง)

สำหรับสิ่งที่คุ้มค่าเราได้เรียกคืนพื้นที่ Blob จากฐานข้อมูลด้วยถ้าไม่ใหญ่เกินไปให้ทำตามขั้นตอนต่อไปนี้ (อย่างไรก็ตามเนื่องจากคุณใช้ SQL Server Express คุณอาจไม่มีที่ว่างลอง)

  1. เพิ่มไฟล์ใหม่ไปยังกลุ่มไฟล์
  2. DBCC SHRINKFILE(file, EMPTYFILE)วิ่ง เนื่องจากคุณลดขนาดแผ่น MDF มันจะล้มเหลวในที่สุดเนื่องจากระบบไม่สามารถย้ายข้อมูลเมตาได้ อย่างไรก็ตามการจัดสรรหยดเปล่าจะไม่ถูกย้าย
  3. DBCC SHRINKFILE(newfile,EMPTYFILE)วิ่ง สิ่งนี้จะย้ายข้อมูลกลับลบด้วยพื้นที่ส่วนเกิน
  4. วางไฟล์ใหม่ (ตอนนี้ว่างเปล่า) จากกลุ่มไฟล์

สิ่งนี้จะช่วยลดการบวม blob ฉันควรพูดถึงว่าเราได้ใช้เทคนิคนี้เป็นหลักในการสร้างฐานข้อมูลที่ว่างเปล่าส่วนใหญ่สำหรับการทดสอบสคริปต์อัพเกรด


-1

จัดระเบียบดัชนีคลัสเตอร์ใหม่ - มีข้อมูลที่โหนดดังนั้น .... มันมีการแยกส่วน


ฉันลองใช้แล้ว: ALTER INDEX ALL ON [MyTableName] REORGANIZE;
DermFrench

3
สร้างใหม่;) ไม่จัดระเบียบใหม่
TomTom
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.