สิ่งนี้ไม่ได้ดูเหมือนว่าจะบ้าจริง ๆ แต่โปรดทราบว่ากล่องโต้ตอบ UI บางอย่างอาจไม่มีข้อมูลที่สมบูรณ์ (นี่คือสาเหตุที่เรามีสิ่งต่าง ๆ เช่นDBCC UPDATEUSAGE ) และการปัดเศษอาจเกี่ยวข้องกับบางส่วนของสิ่งเหล่านั้น การคำนวณ ในที่สุดไดอะล็อกจะแสดงพื้นที่ทั้งหมดสำหรับฐานข้อมูลทั้งหมดของคุณ แต่พื้นที่ที่ไม่ได้ปันส่วนจะคำนวณเฉพาะไฟล์ข้อมูลไม่ใช่ไฟล์บันทึก
มารวมกันบางสิ่ง
- คุณสมบัติฐานข้อมูลและฐานข้อมูลขนาดย่อแสดงสิ่งเดียวกัน (ไม่ใช่ว่าคุณควรอยู่ใน UI ฐานข้อมูลการย่อขนาดอยู่ดี!)
- คุณสมบัติไฟล์ฐานข้อมูลแสดง 17 + 75 = 92 ซึ่งการปัดเศษก่อนการเติมอาจเป็น 91.31 เดียวกันใน 1
- สำหรับการจัดสรรพื้นที่การย่อขนาดสำหรับแต่ละไฟล์แสดง 16.38 + 74.94 = 91.32 - อีกครั้งอาจมีการปัดเศษที่นั่นมิฉะนั้นจะตรงกัน 1
- สำหรับพื้นที่ที่มีอยู่ให้ลดขนาดไฟล์แต่ละไฟล์เป็นที่เดียวที่ฉันสงสัยว่ามีความแตกต่างกันจริงและนี่เป็นเพราะ UI ไม่สอดคล้องกับตำแหน่งที่ได้รับข้อมูลและสถานที่เหล่านี้บางแห่งอาจต้องใช้แคช
ให้ฉันดูสิ่งที่กล่องโต้ตอบที่แตกต่างกันเหล่านี้ทำงานสำหรับสำเนา AdventureWorks2012 ในพื้นที่ของฉัน (โดยมีตารางบางตารางที่ขยายจากสคริปต์นี้ )
EXEC sp_spaceused;
ผลตอบแทนนี้ (ชุดผลลัพธ์แรกเท่านั้น):
database_size unallocated space
------------- -----------------
1545.81 MB 6.67 MB
โดยพื้นฐานแล้วจะรันสิ่งนี้ซึ่ง - ฉันได้รับการยืนยันผ่านการสืบค้น - เป็นคำถามเดียวกันที่ดำเนินการจากคุณสมบัติฐานข้อมูลและกล่องโต้ตอบการย่อขนาดฐานข้อมูล (ฉันแกะสลักส่วนที่ไม่เกี่ยวข้องออกจากกระบวนงานที่เก็บไว้ SSMS ทำเพื่อการแสดงผล):
SELECT database_size = DbSize*8.0/1024 + LogSize*8.0/1024,
[unallocated space] = (DbSize-SpaceUsed)*8.0/1024
FROM
(
SELECT
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
SUM(a.total_pages) AS [SpaceUsed],
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in (1, 3)) AS [LogSize]
FROM sys.partitions p
join sys.allocation_units a on p.partition_id = a.container_id
left join sys.internal_tables it on p.object_id = it.object_id
) AS x;
สิ่งนี้ส่งคืนการแข่งขัน:
database_size unallocated space
------------- -----------------
1545.8125 6.671875
กล่องโต้ตอบเหล่านี้ทั้งหมดแสดงข้อมูลนี้อย่างถูกต้อง กล่องโต้ตอบคุณสมบัติฐานข้อมูล:
กล่องโต้ตอบย่อขนาดฐานข้อมูล:
ไดอะล็อกไฟล์ย่อขนาดจะเรียกใช้คิวรีที่แตกต่างกันเล็กน้อย (อีกครั้งนี่คือการแกะสลัก / ดัดแปลงเพื่อความสะดวก):
SELECT SUBSTRING(name, CHARINDEX('_',name)+1, 4),
[Currently allocated space] = size/1024.0,
[Available free space] = (Size-UsedSpace)/1024.0
FROM
(
SELECT s.name,
CAST(FILEPROPERTY(s.name, 'SpaceUsed') AS float)*CONVERT(float,8) AS [UsedSpace],
s.size * CONVERT(float,8) AS [Size]
FROM sys.database_files AS s
WHERE (s.type IN (0,1))
) AS x;
โปรดทราบว่านอกเหนือจากการรับข้อมูลขนาดจากฟังก์ชั่นแทน DMV แล้วภาคแสดงยังไม่ได้รับการอัพเดตสำหรับไฟล์ประเภทใหม่เช่น filestream / hekaton
ผล:
Currently allocated space Available free space
---- ------------------------- --------------------
Data 1517 7.9375 -- wrong
Log 28.8125 25.671875 -- wrong
ปัญหาคือFILEPROPERTY()
ฟังก์ชั่นซึ่งไม่รับประกันว่าจะทันสมัย (แม้หลังจากDBCC UPDATEUSAGE(0);
รันแล้ว; เพิ่มเติมด้านล่าง) เรื่องนี้จบลงด้วยข้อมูลที่ทำให้เข้าใจผิดบนกล่องโต้ตอบ:
โปรดทราบอีกครั้งว่า 6.67 MB ไม่เคยมีความแม่นยำจริงๆเนื่องจากเป็นเพียงการวัดขนาดฐานข้อมูลทั้งหมด - จำนวนหน้าที่จัดสรรให้โดยไม่สนใจบันทึกทั้งหมด
หากคุณต้องการรายงานพื้นที่ที่ใช้ในฐานข้อมูลอย่างถูกต้องให้หยุดใช้ mickey mouse UIs ซึ่งเรียกใช้การสืบค้นที่แตกต่างกันเพื่อค้นหาสิ่งนี้และหยุดใช้กล่องโต้ตอบไฟล์ย่อขนาดเพื่อดึงข้อมูล สิ่งเหล่านี้อาจมีปัญหาข้อมูลค้างในบางกรณีอย่างชัดเจน เรียกใช้แบบสอบถามจริงกับแหล่งที่คุณเชื่อถือได้ นี่คือสิ่งที่ฉันชอบ:
DECLARE @log_used DECIMAL(19,7);
CREATE TABLE #x(n SYSNAME, s DECIMAL(19,7), u DECIMAL(19,7), b BIT);
INSERT #x EXEC('DBCC SQLPERF(LogSpace);');
SELECT @log_used = u FROM #x WHERE n = DB_NAME();
DROP TABLE #x;
DECLARE @data_used DECIMAL(19,7);
SELECT @data_used = SUM(a.total_pages)*8/1024.0
FROM sys.partitions AS p
INNER JOIN sys.allocation_units AS a
ON p.[partition_id] = a.container_id;
;WITH x(t,s) AS
(
SELECT [type] = CASE
WHEN [type] IN (0,2,4) THEN 'data' ELSE 'log' END,
size*8/1024.0 FROM sys.database_files AS f
)
SELECT
file_type = t,
size = s,
available = s-CASE t WHEN 'data' THEN @data_used ELSE @log_used END
FROM x;
แบบสอบถามนี้ส่งกลับตัวเลขสามตัวที่ควรจะดูคุ้นเคยและเป็นตัวเลขที่ไม่ควร:
file_type size available
--------- ----------- ----------
data 1517.000000 6.6718750
log 28.812500 17.9008512
โปรดทราบว่าDBCC SQLPERFมีแนวโน้มที่จะเกิดปัญหาการใช้พื้นที่เล็กน้อยเช่นหลังจากเรียกใช้:
DBCC UPDATEUSAGE(0);
แบบสอบถามข้างต้นให้ผลตอบแทนนี้แทน:
file_type size available
--------- ----------- ----------
data 1517.000000 8.0781250
log 28.812500 17.8669481
sp_spaceused
ขณะนี้อัตราผลตอบแทนหมายเลขที่ตรงกันเช่นกัน ( 1545.81 MB / 8.08 MB
) แม้ว่า - อีกครั้ง - ที่เป็นเพียงพื้นที่ที่มีอยู่ในข้อมูลไฟล์ (s), และสถานที่ให้บริการฐานข้อมูลและการหดตัวของฐานข้อมูลไดอะล็อกคือ "ความถูกต้อง" เช่นกัน ( แต่กล่องโต้ตอบแฟ้มหดตัวยังคงอยู่ วิธีปิด - FILEPROPERTY()
ดูเหมือนจะไม่ได้รับผลกระทบจากUPDATEUSAGE
เลย):
โอ้และอาจแสดงให้เห็นว่า Windows Explorer คิดอย่างไรกับไฟล์เหล่านี้ดังนั้นคุณสามารถเกี่ยวข้องกับการคำนวณที่ทำเพื่อกำหนด MB:
แน่นอนว่าทั้งหมดนี้จำเป็นต้องมีแน่นอนขึ้นอยู่กับสิ่งที่คุณจะทำกับข้อมูล