SQL सर्वर सिस्टम तालिकाओं को डीफ़्रैग्मेन्ट किया जा सकता है?


15

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

क्या किसी के पास इन मुख्य आंतरिक तालिकाओं पर विखंडन को कम करने के लिए सुझाव हैं? एक स्पष्ट समाधान इतने सारे टेबल बनाने से बच सकता है (या टेम्पर्ड बी में सभी क्षणिक टेबल बनाने के लिए), लेकिन इस प्रश्न के उद्देश्य के लिए मान लें कि एप्लिकेशन में वह लचीलापन नहीं है।

संपादित करें: आगे के शोध इस अनुत्तरित प्रश्न को दर्शाते हैं, जो बारीकी से संबंधित दिखता है और इंगित करता है कि मैनुअल रखरखाव के कुछ प्रकार ALTER INDEX...REORGANIZEएक विकल्प हो सकते हैं।


प्रारंभिक शोध

इन तालिकाओं के बारे में मेटाडेटा में देखा जा सकता है sys.dm_db_partition_stats:

-- The system base table that contains one row for every column in the system
SELECT row_count,
    (reserved_page_count * 8 * 1024.0) / row_count AS bytes_per_row, 
    reserved_page_count/128. AS space_mb
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('sys.syscolpars')
    AND index_id = 1
-- row_count:       15,600,859
-- bytes_per_row:   278.08
-- space_mb:        4,136

हालाँकि, sys.dm_db_index_physical_statsइन तालिकाओं के विखंडन को देखने के लिए समर्थन नहीं करता है:

-- No fragmentation data is returned by sys.dm_db_index_physical_stats
SELECT *
FROM sys.dm_db_index_physical_stats(
    DB_ID(),
    OBJECT_ID('sys.syscolpars'),
    NULL,
    NULL,
    'DETAILED'
)

ओला हैलेनग्रेन की लिपियों में is_ms_shipped = 1वस्तुओं के लिए डीफ़्रैग्मेन्टेशन पर विचार करने के लिए एक पैरामीटर भी होता है , लेकिन इस पैरामीटर को सक्षम करने के साथ प्रक्रिया चुपचाप सिस्टम बेस तालिकाओं को भी अनदेखा कर देती है। ओला ने स्पष्ट किया कि यह अपेक्षित व्यवहार है; केवल उपयोगकर्ता टेबल (सिस्टम टेबल नहीं) जो ms_shipped (उदा msdb.dbo.backupset) माना जाता है।

-- Returns code 0 (successful), but does not do any work for system base tables.
-- Instead of the expected commands to update statistics and reorganize indexes,
-- no commands are generated. The script seems to assume the target tables will
-- appear in sys.tables, but this does not appear to be a valid assumption for
-- system tables like sys.sysrowsets or sys.syscolpars.
DECLARE @result int;
EXEC @result = IndexOptimize @Databases = 'Test',
        @FragmentationLow = 'INDEX_REORGANIZE',
        @FragmentationMedium = 'INDEX_REORGANIZE',
        @FragmentationHigh = 'INDEX_REORGANIZE',
        @PageCountLevel = 0,
        @UpdateStatistics = 'ALL',
        @Indexes = '%Test.sys.sysrowsets.%',
        -- Proc works properly if targeting a non-system table instead
        --@Indexes = '%Test.dbo.Numbers.%',
        @MSShippedObjects = 'Y',
        @Execute = 'N';
PRINT(@result);


अतिरिक्त अनुरोधित जानकारी

मैंने निरीक्षण प्रणाली टेबल बफर पूल के उपयोग के नीचे हारून की क्वेरी का एक अनुकूलन का उपयोग किया, और यह पाया कि बफर डेटाबेस में केवल एक डेटाबेस के लिए दसियों जीबी सिस्टम टेबल हैं, उस जगह का ~ 80% कुछ मामलों में मुक्त स्थान है। ।

-- Compute buffer pool usage by system table
SELECT OBJECT_NAME(p.object_id),
    COUNT(b.page_id) pages,
    SUM(b.free_space_in_bytes/8192.0) free_pages
FROM sys.dm_os_buffer_descriptors b
JOIN sys.allocation_units a
    ON a.allocation_unit_id = b.allocation_unit_id
JOIN sys.partitions p
    ON p.partition_id = a.container_id
    AND p.object_id < 1000 -- A loose proxy for system tables
WHERE b.database_id = DB_ID()
GROUP BY p.object_id
ORDER BY pages DESC

यहाँ छवि विवरण दर्ज करें

जवाबों:


11

क्या आप सुनिश्चित हैं कि आपने इस सिस्टम टेबल को "बफर पूल पर अनावश्यक दबाव" के एकमात्र स्रोत के रूप में सकारात्मक और सटीक रूप से पहचाना है और किसी डेटाबेस में सभी तालिकाओं के आकार की गणना जैसे संचालन के प्रदर्शन को भी नकारात्मक रूप से प्रभावित करता है? क्या आप सुनिश्चित हैं कि यह सिस्टम टेबल इस तरह से स्व-प्रबंधित नहीं है कि (a) विखंडन को कम से कम किया जाए या गुप्त रूप से रखा जाए या (b) मेमोरी में कुशलतापूर्वक प्रबंधित किया जाए ताकि डीफ़्रैग्मेन्टेशन का स्तर वास्तव में कुछ भी प्रभावित न करे?

आप देख सकते हैं कितने पृष्ठों उपयोग में हैं, और आप देख सकते हैं कि कितना मुक्त अंतरिक्ष पर है कि पृष्ठों स्मृति में हैं ( page_free_space_percentहमेशा NULLआवंटन DMF में है, लेकिन यह है बफर DMV से उपलब्ध है) - यह आपको कुछ पता चलना चाहिए यदि आप जिस चीज के बारे में चिंता कर रहे हैं वह वास्तव में ऐसी चीज है जिसके बारे में आपको चिंतित होना चाहिए:

SELECT 
  Number_of_Pages = COUNT(*), 
  Number_of_Pages_In_Memory = COUNT(b.page_id),
  Avg_Free_Space = AVG(b.free_space_in_bytes/8192.0) 
FROM sys.dm_db_database_page_allocations
(
  DB_ID(),
  OBJECT_ID(N'sys.syscolpars'),
  NULL,NULL,'DETAILED'
) AS p
LEFT OUTER JOIN sys.dm_os_buffer_descriptors AS b
ON b.database_id = DB_ID() 
AND b.page_id = p.allocated_page_page_id 
AND b.file_id = p.allocated_page_file_id;

यदि आपके पृष्ठों की संख्या छोटी है (जैसे सिस्टम तालिकाओं के लिए शायद <10000) या यदि रिक्त स्थान "कम" है (यह सुनिश्चित नहीं है कि आपके विशिष्ट थ्रॉल्ड्स रीगॉर / पुनर्निर्माण के लिए हैं), तो अन्य, अधिक रोचक, कम लटकने वाले फलों पर ध्यान दें ।

यदि आपके पृष्ठों की संख्या बड़ी है और मुक्त स्थान "उच्च" है, ठीक है, तो शायद मैं एसक्यूएल सर्वर को अपने स्वयं के रखरखाव के लिए बहुत अधिक क्रेडिट दे रहा हूं। जैसा कि आपने दूसरे प्रश्न से दिखाया है , यह काम करता है ...

ALTER INDEX ALL ON sys.syscolpars REORGANIZE;

... और विखंडन को कम करता है। हालांकि इसके लिए एलिवेटेड परमिशन की जरूरत पड़ सकती है (मैंने चपरासी की तरह कोशिश नहीं की)।

हो सकता है कि आप इसे समय-समय पर अपने स्वयं के रखरखाव के हिस्से के रूप में कर सकते हैं, अगर यह आपको अच्छा महसूस कराता है और / या आपके पास कोई सबूत है कि इसका आपके सिस्टम पर कोई सकारात्मक प्रभाव पड़ता है।


मैंने एक और जवाब जोड़ते हुए कहा कि हमने जो किया, उसे समाप्त किया और फिर पिछली टिप्पणियों को यहाँ साफ किया। आपकी सहायता के लिए एक बार फिर से धन्यवाद!
ज्यॉफ पैटरसन

7

हारून के जवाब के साथ-साथ अतिरिक्त शोध के मार्गदर्शन के आधार पर, यहां मेरे द्वारा लिए गए दृष्टिकोण का त्वरित लेखन है।

मैं जो बता सकता हूं, उसमें सिस्टम बेस टेबल के विखंडन के निरीक्षण के विकल्प सीमित हैं। मैंने आगे जाकर बेहतर दृश्यता प्रदान करने के लिए एक कनेक्ट मुद्दा दायर किया , लेकिन इस बीच ऐसा लगता है कि विकल्पों में बफर पूल की जांच या प्रति पंक्ति औसत # बाइट्स की जाँच करना शामिल है।

मैंने तब सभी सिस्टम बेस टेबल पर `ALTER INDEX ... REORGANIZE प्रदर्शन करने के लिए एक प्रक्रिया बनाई । इस प्रक्रिया को हमारे कुछ सबसे अधिक इस्तेमाल किए जाने वाले देव सर्वरों ने दिखाया कि सिस्टम बेस टेबलों के संचयी आकार को 50GB (सिस्टम पर ~ 5MM उपयोगकर्ता तालिकाओं के साथ) ट्रिम किया गया था, इसलिए स्पष्ट रूप से एक चरम मामला है।

हमारे रात्रिकालीन रखरखाव कार्यों में से एक, जो विभिन्न यूनिट परीक्षणों और विकास द्वारा बनाई गई कई उपयोगकर्ता तालिकाओं को साफ करने में मदद करता है, पहले इसे पूरा करने में ~ 50 मिनट लगते थे। का एक संयोजन sp_whoisactive, sys.dm_os_waiting_tasksऔर DBCC PAGEपता चला है कि प्रतीक्षा करता है मैं / प्रणाली आधार टेबल पर हे का बोलबाला रहा।

सभी सिस्टम बेस तालिकाओं के पुनर्गठन के बाद, रखरखाव कार्य ~ 15 मिनट तक गिर गया। अभी भी कुछ आई / ओ इंतजार कर रहे थे, लेकिन वे काफी कम हो गए थे, शायद कम विखंडन के कारण कैश और / या अधिक रीडहेड्स में शेष डेटा की अधिक मात्रा के कारण।

इसलिए, मेरा निष्कर्ष यह है कि ALTER INDEX...REORGANIZEएक रखरखाव योजना में सिस्टम बेस टेबल के लिए जोड़ने पर विचार करना एक उपयोगी बात हो सकती है, लेकिन संभावना केवल तभी होती है जब आपके पास एक परिदृश्य होता है जहां डेटाबेस पर असामान्य संख्या में ऑब्जेक्ट बनाए जा रहे हैं।


आपके प्रश्न और उत्तर दोनों के लिए +1 - इंटर्नल एक ब्लैक बॉक्स का एक सा है, और आपने प्रदर्शन के लिए वास्तव में बुरा परिदृश्य जैसा दिखने पर कुछ प्रकाश डालने में मदद की है। है किनारे से मामला)।
मैक्स वर्नोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.