SQL सर्वर में तालिका और सूचकांक आकार


90

क्या हमारे पास SQL ​​क्वेरी हो सकती है जो मूल रूप से SQl सर्वर में टेबल और इंडेक्स साइज देखने में मदद करेगी।

SQL सर्वर टेबल / इंडेक्स के लिए मेमोरी का उपयोग कैसे करता है?


1
आपको संग्रहीत कार्यविधि sp_helpdbउपयोगी भी लग सकती है
ज़ैक बर्ट

1
इसके उत्तर पहले से ही हैं, लेकिन मैं व्यक्तिगत रूप से इस लिंक में क्वेरी का उपयोग करता हूं: qualityofdata.com/2011/02/02/…
naiem

जवाबों:


73

exec sp_spaceusedपैरामीटर के बिना पूरे डेटाबेस के लिए सारांश दिखाता है। Foreachtable समाधान प्रति तालिका एक सेट सेट उत्पन्न करता है - जिसे SSMS संभाल नहीं सकता है यदि आपके पास बहुत अधिक टेबल हैं।

मैंने एक स्क्रिप्ट बनाई जो तालिका infos एकत्र करती है sp_spaceusedऔर एक एकल रिकॉर्ड सेट में एक सारांश प्रदर्शित करती है, आकार द्वारा क्रमबद्ध।

create table #t
(
  name nvarchar(128),
  rows varchar(50),
  reserved varchar(50),
  data varchar(50),
  index_size varchar(50),
  unused varchar(50)
)

declare @id nvarchar(128)
declare c cursor for
select '[' + sc.name + '].[' + s.name + ']' FROM sysobjects s INNER JOIN sys.schemas sc ON s.uid = sc.schema_id where s.xtype='U'

open c
fetch c into @id

while @@fetch_status = 0 begin

  insert into #t
  exec sp_spaceused @id

  fetch c into @id
end

close c
deallocate c

select * from #t
order by convert(int, substring(data, 1, len(data)-3)) desc

drop table #t

4
आपकी स्क्रिप्ट केवल स्कीमा 'dbo' में तालिकाओं को संभालती है। यदि मेरे पास 'ऑडिट' के स्कीमा के साथ मेरे डेटाबेस में एक तालिका है, तो sp_spaceused को इस तरह से बुलाया जाना चाहिए: sp_spaceused 'ऑडिट.डाटा' निष्पादित करें। इसलिए स्क्रिप्ट को अन्य स्कीमा से तालिका के बारे में डेटा वापस करने के लिए इसे स्कीमा नाम (पूर्व से अलग) द्वारा दिए गए तालिका नाम को फीड करने के लिए संशोधित करने की आवश्यकता है।
बोडाद

1
अच्छा बिंदु @ बोडाद ... जो एक सुपर आसान फिक्स होना चाहिए। इसके साथ "चयन नाम को sysobjects से बदल दें जहां xtype = 'U'" इसके साथ ट्रिक करना चाहिए: "select" ['+ sc.name +']। ['+ + s.name +'] '' Sysobjectred s INNER JOIN sys से। .schemas sc on s.uid = sc.schema_id जहाँ s.xtype = 'U' "Great script, धन्यवाद!
DCaugs

अस्थायी तालिका का उपयोग करने के बजाय क्या हम अन्य तालिका में डेटा सम्मिलित कर सकते हैं जो अस्थायी नहीं है?
प्रभाकर

@PrabhakarPandey ज़रूर बस को दूर #
रेसर एसक्यूएल

120

Sp_spaceused आपको सभी अनुक्रमित संयुक्त का आकार देता है।

यदि आप तालिका के लिए प्रत्येक सूचकांक का आकार चाहते हैं, तो इन दो प्रश्नों में से एक का उपयोग करें:

SELECT
    i.name                  AS IndexName,
    SUM(s.used_page_count) * 8   AS IndexSizeKB
FROM sys.dm_db_partition_stats  AS s 
JOIN sys.indexes                AS i
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
WHERE s.[object_id] = object_id('dbo.TableName')
GROUP BY i.name
ORDER BY i.name

SELECT
    i.name              AS IndexName,
    SUM(page_count * 8) AS IndexSizeKB
FROM sys.dm_db_index_physical_stats(
    db_id(), object_id('dbo.TableName'), NULL, NULL, 'DETAILED') AS s
JOIN sys.indexes AS i
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
GROUP BY i.name
ORDER BY i.name

परिणाम आमतौर पर थोड़ा अलग होते हैं लेकिन 1% के भीतर।


पहली क्वेरी में प्राथमिक कुंजी शामिल है, जो कुछ कारणों के लिए थोड़ा भ्रमित है।
क्विलब्रेकर

दूसरी क्वेरी Msg 102, Level 15, State 1, Line 5 - Incorrect syntax near '('.मुझ पर फेंकती है, लेकिन मैं सिंटैक्स के साथ कोई समस्या नहीं देख सकता। कोई उपाय?
ओलिवर

ओलिवर, आप किस संस्करण पर चल रहे हैं? यह 2008R2 और 2012 में मेरे लिए काम करता है।
रोब गैरीसन

24

SQL 2012 में एक टेबल स्तर पर यह जानकारी प्राप्त करना स्वादिष्ट रूप से सरल हो गया है:

SQL प्रबंधन स्टूडियो -> Db पर राइट क्लिक करें -> रिपोर्ट -> मानक रिपोर्ट -> तालिका द्वारा डिस्क का उपयोग!

का आनंद लें


13
EXEC sp_MSforeachtable @command1="EXEC sp_spaceused '?'"

3
यदि आप कोड, XML या डेटा नमूने पोस्ट करते हैं, तो कृपया टेक्स्ट एडिटर में उन पंक्तियों को हाइलाइट करें और { }एडिटर टूलबार पर "कोड सैंपल" बटन ( ) पर क्लिक करके अच्छी तरह से फॉर्मेट करें और सिंटैक्स इसे हाइलाइट करें!
marc_s

4
--Gets the size of each index for the specified table
DECLARE @TableName sysname = N'SomeTable';

SELECT i.name AS IndexName
      ,8 * SUM(s.used_page_count) AS IndexSizeKB
FROM sys.indexes AS i
    INNER JOIN sys.dm_db_partition_stats AS s 
        ON i.[object_id] = s.[object_id] AND i.index_id = s.index_id
WHERE s.[object_id] = OBJECT_ID(@TableName, N'U')
GROUP BY i.name
ORDER BY i.name;

SELECT i.name AS IndexName
      ,8 * SUM(a.used_pages) AS IndexSizeKB
FROM sys.indexes AS i
    INNER JOIN sys.partitions AS p 
        ON i.[object_id]  = p.[object_id] AND i.index_id = p.index_id
    INNER JOIN sys.allocation_units AS a 
        ON p.partition_id = a.container_id
WHERE i.[object_id] = OBJECT_ID(@TableName, N'U')
GROUP BY i.name
ORDER BY i.name;

3

यहां सबसे सफल उत्तर का अधिक कॉम्पैक्ट संस्करण है:

create table #tbl(
  name nvarchar(128),
  rows varchar(50),
  reserved varchar(50),
  data varchar(50),
  index_size varchar(50),
  unused varchar(50)
)

exec sp_msforeachtable 'insert into #tbl exec sp_spaceused [?]'

select * from #tbl
    order by convert(int, substring(data, 1, len(data)-3)) desc

drop table #tbl

3

इस पोस्ट के निर्माण के बाद एक लंबा समय हो रहा है लेकिन मैं अपनी स्क्रिप्ट साझा करना चाहता था:

WITH CteIndex
AS
(
SELECT 
     reservedpages = (reserved_page_count)
     ,usedpages = (used_page_count)
     ,pages = (
            CASE
                WHEN (s.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
                ELSE lob_used_page_count + row_overflow_used_page_count
            END
            )    
     ,s.object_id   
     ,i.index_id        
     ,i.type_desc AS IndexType
     ,i.name AS indexname
    FROM sys.dm_db_partition_stats s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id   
)
SELECT DISTINCT
DB_NAME(DB_ID()) AS DatabaseName
,o.name AS TableName
,o.object_id
,ct.indexname
,ct.IndexType
,ct.index_id
, IndexSpace = LTRIM (STR ((CASE WHEN usedpages > pages THEN CASE WHEN ct.index_id < 2 THEN  pages ELSE (usedpages - pages) END ELSE 0 END) * 8, 15, 0) + ' KB')
FROM CteIndex ct
INNER JOIN sys.objects o ON o.object_id = ct.object_id
INNER JOIN sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL , NULL) ps ON ps.object_id = o.object_id
AND ps.index_id = ct.index_id
ORDER BY name ASC

इसके लिए काम करता है:

  • SQL सर्वर (2008 से शुरू)
  • वर्तमान डेटाबेस प्रति सभी तालिकाओं के लिए जानकारी शामिल है

0

एक विस्तारित संग्रहीत प्रक्रिया है sp_spaceusedजो इस जानकारी को बाहर निकालती है। यह डेटा शब्दकोश से करने के लिए काफी हद तक जटिल है, लेकिन यह लिंक एक स्क्रिप्ट से बाहर है जो इसे करता है। इस स्टैकओवरफ़्लो प्रश्न में अंतर्निहित डेटा संरचनाओं के बारे में जानकारी के लिए कुछ प्रशंसक हैं जिनका उपयोग आप कैपिसिटी योजना के लिए तालिका और सूचकांक आकार के अनुमानों का निर्माण करने के लिए कर सकते हैं।


0

यह प्रश्न दो अन्य उत्तरों से आता है:

डेटाबेस में सभी तालिकाओं का आकार प्राप्त करें

SQL सर्वर डेटाबेस में सबसे बड़ी वस्तुओं को खोजने के लिए कैसे?

, लेकिन मैंने इसे सार्वभौमिक बनाने के लिए बढ़ाया। यह sys.objectsशब्दकोश का उपयोग करता है :

SELECT 
    s.NAME as SCHEMA_NAME,
    t.NAME AS OBJ_NAME,
    t.type_desc as OBJ_TYPE,
    i.name as indexName,
    sum(p.rows) as RowCounts,
    sum(a.total_pages) as TotalPages, 
    sum(a.used_pages) as UsedPages, 
    sum(a.data_pages) as DataPages,
    (sum(a.total_pages) * 8) / 1024 as TotalSpaceMB, 
    (sum(a.used_pages) * 8) / 1024 as UsedSpaceMB, 
    (sum(a.data_pages) * 8) / 1024 as DataSpaceMB
FROM 
    sys.objects t
INNER JOIN
    sys.schemas s ON t.SCHEMA_ID = s.SCHEMA_ID 
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
    t.NAME NOT LIKE 'dt%' AND
    i.OBJECT_ID > 255 AND   
    i.index_id <= 1
GROUP BY 
    s.NAME, t.NAME, t.type_desc, i.object_id, i.index_id, i.name 
ORDER BY
    sum(a.total_pages) DESC
;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.