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


136

मैं SQL सर्वर डेटाबेस में सबसे बड़ी वस्तुओं को खोजने के बारे में कैसे जाना होगा? सबसे पहले, यह निर्धारित करके कि कौन सी तालिकाएँ (और संबंधित सूचकांक) सबसे बड़ी हैं और फिर यह निर्धारित करना कि किसी विशेष तालिका में कौन सी पंक्तियाँ सबसे बड़ी हैं (हम BLOB में बाइनरी डेटा संग्रहीत कर रहे हैं)?

क्या इस तरह के डेटाबेस विश्लेषण में मदद करने के लिए कोई उपकरण हैं? या कुछ साधारण प्रश्न हैं जो मैं सिस्टम टेबल के खिलाफ चला सकता हूं?

जवाबों:


280

मैं इस एसक्यूएल स्क्रिप्ट का उपयोग कर रहा हूं (जो मुझे किसी से मिला, कहीं - उम्र के लिए इसे फिर से प्राप्त नहीं कर सकता) जिसने इसे समझने और सूचकांकों और तालिकाओं के आकार को समझने में काफी मदद की:

SELECT 
    t.name AS TableName,
    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.tables t
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 
    t.name, i.object_id, i.index_id, i.name 
ORDER BY 
    object_name(i.object_id) 

बेशक, आप एक और आदेश मानदंड का उपयोग कर सकते हैं, जैसे

ORDER BY SUM(p.rows) DESC

सबसे पंक्तियों के साथ तालिकाओं को पाने के लिए, या

ORDER BY SUM(a.total_pages) DESC

सबसे अधिक पृष्ठों (8K ब्लॉक) के साथ तालिकाओं का उपयोग करने के लिए।


बहुत बड़िया धन्यवाद! अब, जब मैंने अपने सबसे बड़े ऑब्जेक्ट को एक मेज पर रख दिया है जिसमें बहुत सारे बाइनरी डेटा हैं, वैसे भी यह पता लगाने के लिए कि बाइनरी डेटा की कौन सी पंक्तियाँ सबसे बड़ी हैं?
jamesaharvey

3
उसके लिए, आपको उस तालिका पर एक चयन करना होगा और प्रत्येक क्षेत्र के लिए DATALENGTH (फ़ील्ड) का प्रिंट आउट करना होगा, जिसमें आप रुचि रखते हैं (आमतौर पर VARCHAR (MAX), VARBINARY (MAX) और इसके बाद)
marc_n

1
धन्यवाद @marc_s, यह बहुत उपयोगी था। TableName कॉलम में स्कीमा का नाम भी शामिल हो सकता हैSELECT OBJECT_SCHEMA_NAME(i.object_id) + '.' + OBJECT_NAME(i.object_id) AS TableName, ...
क्रूज़ेन

2
वह सबसे खूबसूरत TSQL स्क्रिप्ट होनी चाहिए जिसे मैंने कभी देखा है
Agustin Meriles

2
NON-CLUSTERED इंडेक्स को भी शामिल करने के लिए WHO क्लॉज से "i.index_id <= 1" निकालें।
गॉर्डन बेल

72

SQL Server 2008 में, आप बस टॉप टेबल्स द्वारा मानक रिपोर्ट डिस्क उपयोग भी चला सकते हैं। यह DB पर राइट क्लिक करके , रिपोर्ट्स-> स्टैंडर्ड रिपोर्ट्स का चयन करके और इच्छित रिपोर्ट का चयन करके पाया जा सकता है ।


8
मजाक नहीं? यह एक ऐसा क्रांतिकारी जवाब है। इसे पोस्ट करने के लिए धन्यवाद। (व्यंग्य नहीं। अभी कुछ समय से इन प्रश्नों को मैन्युअल रूप से चला रहे हैं और मुझे विश्वास नहीं हो रहा है कि ये रिपोर्ट पहले से हैं!)
जेनिफर ज़ौक

4

यह क्वेरी आपके कनेक्शन में सबसे बड़ी तालिका खोजने में मदद करती है।

SELECT  TOP 1 OBJECT_NAME(OBJECT_ID) TableName, st.row_count
FROM sys.dm_db_partition_stats st
WHERE index_id < 2
ORDER BY st.row_count DESC

कुछ ऐसा होना अच्छा है जिसे हम आसानी से याद कर सकें। आभार के लिए धन्यवाद।
डेविड बेट्ज़

3

आप निम्न कोड का भी उपयोग कर सकते हैं:

USE AdventureWork
GO
CREATE TABLE #GetLargest 
(
  table_name    sysname ,
  row_count     INT,
  reserved_size VARCHAR(50),
  data_size     VARCHAR(50),
  index_size    VARCHAR(50),
  unused_size   VARCHAR(50)
)

SET NOCOUNT ON

INSERT #GetLargest

EXEC sp_msforeachtable 'sp_spaceused ''?'''

SELECT 
  a.table_name,
  a.row_count,
  COUNT(*) AS col_count,
  a.data_size
  FROM #GetLargest a
     INNER JOIN information_schema.columns b
     ON a.table_name collate database_default
     = b.table_name collate database_default
       GROUP BY a.table_name, a.row_count, a.data_size
       ORDER BY CAST(REPLACE(a.data_size, ' KB', '') AS integer) DESC

DROP TABLE #GetLargest

2

यदि आप Sql Server Management Studio 2008 का उपयोग कर रहे हैं, तो कुछ डेटा फ़ील्ड हैं जो आप ऑब्जेक्ट एक्सप्लोरर विवरण विंडो में देख सकते हैं। बस टेबल फोल्डर को ब्राउज़ करें और चुनें। विवरण दृश्य में आप कॉलम के शीर्षक पर राइट-क्लिक कर सकते हैं और "रिपोर्ट" में फ़ील्ड जोड़ सकते हैं। यदि आप SSMS 2008 एक्सप्रेस पर हैं तो आपका माइलेज भिन्न हो सकता है।


2

मैंने इस क्वेरी को SqlServerCentral में भी बहुत उपयोगी पाया है, यहाँ मूल पोस्ट की लिंक दी गई है

Sql सर्वर सबसे बड़ी टेबल

  select name=object_schema_name(object_id) + '.' + object_name(object_id)
, rows=sum(case when index_id < 2 then row_count else 0 end)
, reserved_kb=8*sum(reserved_page_count)
, data_kb=8*sum( case 
     when 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 )
, index_kb=8*(sum(used_page_count) 
    - sum( case 
           when 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 )
     )    
, unused_kb=8*sum(reserved_page_count-used_page_count)
from sys.dm_db_partition_stats
where object_id > 1024
group by object_id
order by 
rows desc   

मेरे डेटाबेस में उन्होंने इस प्रश्न और 1 उत्तर के बीच अलग-अलग परिणाम दिए।

आशा है कि किसी को उपयोगी लगता है


1

@ marc_s का उत्तर बहुत शानदार है और मैं कुछ वर्षों से इसका उपयोग कर रहा हूं। हालाँकि, मैंने देखा कि स्क्रिप्ट कुछ कॉलमस्टोर इंडेक्स में डेटा को याद करती है और पूरी तस्वीर नहीं दिखाती है। जब आप SUM(TotalSpace)स्क्रिप्ट के खिलाफ करते हैं और प्रबंधन स्टूडियो में कुल अंतरिक्ष डेटाबेस संपत्ति के साथ तुलना करते हैं तो संख्या मेरे मामले में मेल नहीं खाती है (प्रबंधन स्टूडियो बड़ी संख्या दिखाता है)। मैंने इस मुद्दे पर काबू पाने के लिए स्क्रिप्ट को संशोधित किया और इसे थोड़ा बढ़ाया:

select
    tables.[name] as table_name,
    schemas.[name] as schema_name,
    isnull(db_name(dm_db_index_usage_stats.database_id), 'Unknown') as database_name,
    sum(allocation_units.total_pages) * 8 as total_space_kb,
    cast(round(((sum(allocation_units.total_pages) * 8) / 1024.00), 2) as numeric(36, 2)) as total_space_mb,
    sum(allocation_units.used_pages) * 8 as used_space_kb,
    cast(round(((sum(allocation_units.used_pages) * 8) / 1024.00), 2) as numeric(36, 2)) as used_space_mb,
    (sum(allocation_units.total_pages) - sum(allocation_units.used_pages)) * 8 as unused_space_kb,
    cast(round(((sum(allocation_units.total_pages) - sum(allocation_units.used_pages)) * 8) / 1024.00, 2) as numeric(36, 2)) as unused_space_mb,
    count(distinct indexes.index_id) as indexes_count,
    max(dm_db_partition_stats.row_count) as row_count,
    iif(max(isnull(user_seeks, 0)) = 0 and max(isnull(user_scans, 0)) = 0 and max(isnull(user_lookups, 0)) = 0, 1, 0) as no_reads,
    iif(max(isnull(user_updates, 0)) = 0, 1, 0) as no_writes,
    max(isnull(user_seeks, 0)) as user_seeks,
    max(isnull(user_scans, 0)) as user_scans,
    max(isnull(user_lookups, 0)) as user_lookups,
    max(isnull(user_updates, 0)) as user_updates,
    max(last_user_seek) as last_user_seek,
    max(last_user_scan) as last_user_scan,
    max(last_user_lookup) as last_user_lookup,
    max(last_user_update) as last_user_update,
    max(tables.create_date) as create_date,
    max(tables.modify_date) as modify_date
from 
    sys.tables
    left join sys.schemas on schemas.schema_id = tables.schema_id
    left join sys.indexes on tables.object_id = indexes.object_id
    left join sys.partitions on indexes.object_id = partitions.object_id and indexes.index_id = partitions.index_id
    left join sys.allocation_units on partitions.partition_id = allocation_units.container_id
    left join sys.dm_db_index_usage_stats on tables.object_id = dm_db_index_usage_stats.object_id and indexes.index_id = dm_db_index_usage_stats.index_id
    left join sys.dm_db_partition_stats on tables.object_id = dm_db_partition_stats.object_id and indexes.index_id = dm_db_partition_stats.index_id
group by schemas.[name], tables.[name], isnull(db_name(dm_db_index_usage_stats.database_id), 'Unknown')
order by 5 desc

आशा है कि यह किसी के लिए उपयोगी होगा। यह स्क्रिप्ट सैकड़ों अलग-अलग टेबल, इंडेक्स और स्कीमा के साथ बड़े टीबी-वाइड डेटाबेस के खिलाफ परीक्षण किया गया था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.