Розмір бази даних - МДФ занадто великий?


10

Я підтримую базу даних SQL Server 2005, в якій розміщено приблизно 2,9 Тб даних (2 х 1,45 Тб - у мене є схема RAW та схема АНАЛІЗУ, в основному дві копії даних, що приймаються). Модель відновлення - ПРОСТА, а значення .ldf- 6 Гбіт.

З будь-якої причини, .mdf 7,5 Тб. Тепер у таблицях АНАЛІЗУ є лише, можливо, 2–3 додаткові стовпчики, і не так багато NVARCHAR(MAX)стовпців, які з того, що я (можливо, помилково зрозумів - будь ласка, виправте мене, якщо я помиляюся) може спричинити додатковий розподіл місця. Це після скорочення бази даних зараз - до цього вона становила ~ 9Tb. Будь-які думки?

І, будь ласка, дайте мені знати, якщо у вас є додаткові запитання - я дуже новачок в управлінні базами даних та зусиллях по оптимізації (я зазвичай не виконую цю сторону роботи :)).

Дуже дякую!

Андрія


Дякую Марку - будь-яким способом я можу перенести це питання туди чи мені потрібно повторно публікувати повідомлення?

Ура - як ви, напевно, здогадуєтесь, я тут новий :)

Відповіді:


11

Чи враховували ви у своїх оцінках розміру кількість місця, що займає індекси? Крім того, якщо у вас є текстові поля, які встановлені як багатобайтові ( N[VAR]CHARа не [VAR]CHAR), а вхідні файли UTF-8 або звичайний один байт на символ, то це підніме ваші вимоги до пам’яті до двох разів. Крім того, пам’ятайте, що якщо у вас є кластерний ключ / індекс в таблиці, розмір цього впливу впливає на всі інші індекси в таблиці, оскільки вони включають значення кластеризованого ключа для кожного рядка (так, щоб навести крайній приклад, якщо таблиця має NCHAR (10 ) введіть туди, де буде робитися INT, і це ваш кластерний ключ / індекс, ви не тільки використовуєте додаткові 16 байт на рядок на сторінках даних, а також витрачаєте 16 байт на рядок у кожному іншому індексі цієї таблиці ) .

Крім того, деякий простір буде виділено, але невикористаний, або тому, що двигун БД залишив деякий простір, виділений після видалення, щоб його можна було знову використовувати швидко для нових даних у цій таблиці, або тому, що шаблон вставки та видалення залишив для багатьох сторінок лише частину повний.

Ви можете запустити:

SELECT o.name
     , SUM(ps.reserved_page_count)/128.0 AS ReservedMB
     , SUM(ps.used_page_count)/128.0 AS UsedMB
     , SUM(ps.reserved_page_count-ps.used_page_count)/128.0 AS DiffMB
FROM sys.objects o  
JOIN sys.dm_db_partition_stats ps ON o.object_id = ps.object_id  
WHERE OBJECTPROPERTYEX(o.object_id, 'IsMSShipped') = 0  
GROUP BY o.name  
ORDER BY SUM(ps.reserved_page_count) DESC

щоб швидко подивитися, які таблиці займають місце.

Також EXEC sp_spaceusedзапуск у цій БД поверне два набори результатів. Перший перераховує загальний простір, що виділяється у файловій системі для файлів даних, і яка частина нерозподіленої, друга перераховує, скільки виділеного простору використовується для сторінок даних, для покажчикових сторінок або наразі не використовується.

sp_spaceused також поверне простір, який використовується даним об'єктом, і ви можете зафіксувати це, щоб створити таблицю для аналізу:

-- TEMP TABLES FOR ANALYSIS
CREATE TABLE #tTables (sName NVARCHAR(MAX), iRows BIGINT, iReservedKB BIGINT, iDataKB BIGINT, iIndexKB BIGINT, iUnusedKB BIGINT)
CREATE TABLE #tTmp (sName NVARCHAR(MAX), iRows BIGINT, sReservedKB NVARCHAR(MAX), sDataKB NVARCHAR(MAX), sIndexKB NVARCHAR(MAX), sUnusedKB NVARCHAR(MAX))
-- COLLECT SPACE USE PER TABLE
EXEC sp_msforeachtable 'INSERT #tTmp EXEC sp_spaceused [?];'
-- CONVERT NUMBER-AS-TEXT COLUMNS TO NUMBER TYPES FOR EASIER ANALYSIS
INSERT #tTables SELECT sName, iRows
                     , CAST(REPLACE(sReservedKB, ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sDataKB    , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sIndexKB   , ' KB', '') AS BIGINT)
                     , CAST(REPLACE(sUnusedKB  , ' KB', '') AS BIGINT) 
                FROM #tTmp
DROP TABLE #tTmp 
-- DO SOME ANALYSIS 
SELECT sName='TOTALS', iRows=SUM(iRows), iReservedKB=SUM(iReservedKB), iDataKB=SUM(iDataKB),  iIndexKB=SUM(iIndexKB), iUnusedKB=SUM(iUnusedKB) FROM #tTables ORDER BY sName
SELECT * FROM #tTables ORDER BY iReservedKB DESC
-- CLEAN UP
DROP TABLE #tTables

Вищевказаний код виведе всі розміри таблиці в один список плюс один рядок для підсумків. При необхідності ви можете використовувати різні види системи (як sys.objectsі sys.dm_db_partition_statsвикористовувані в першому запиті вище, див http://technet.microsoft.com/en-us/library/ms177862.aspx для набагато більш детально) , щоб отримати більш детальну інформацію , наприклад, простір, що використовується кожним індексом.


У файлі даних є три класи невикористаного простору:

  1. Те, що не виділено ні на що (це показує в першому наборі результатів sp_spaceusedз не вказаним об'єктом)
  2. Те, що виділено об'єкту (зарезервовано), але в даний час не використовується (це відображається у "невикористаному" рахунку у sp_spaceusedвихідних даних.
  3. Що заблоковано на сторінках, що використовуються частково (це, схоже, буде використано, оскільки все розподіляється по одних фрагментах сторінок, одна сторінка має довжину 8,192 байт). Це важче виявити / обчислити. Це пов'язано з поєднанням двох факторів:
    • Розділити сторінки. Коли дані додаються, ви часто стикаєтесь із частиною порожніх сторінок (механізм зберігання даних завжди може нормалізувати вміст сторінки, але це було б дуже неефективно), і як видалені рядки вміст сторінки автоматично не упаковується (знову це може бути, але додатково Навантаження вводу / виводу, як правило, далеко не варто).
    • Двигун пам’яті не розділить рядок на кілька сторінок (це разом із розміром сторінки, звідки походить обмеження 8,192 байт на рядок). Якщо ваші рядки мають фіксований розмір і беруть по 1100 байт, тоді ви збираєтеся "витрачати" щонайменше 492 байти кожного блоку даних, виділеного до цієї таблиці (7 рядків займають 7 700 байт, а 8-й не підходить, тому решта байт виграли " t використовувати). Чим ширші рядки, тим гірше це може бути. Таблиці / покажчики з рядками змінної довжини (які набагато частіші, ніж цілком фіксованої довжини), як правило, краще (але обчислення не так просто).
      Ще один застереження тут - великі об'єкти ( TEXTстовпці,[N]VARCHAR(MAX) значення вище певного розміру тощо), оскільки вони розміщуються поза сторінкою, просто беручи 8 байт у даних основного рядка, щоб утримувати вказівник на дані в інших місцях), таким чином, можна порушити 8,192 байт на рядок-межа.

tl; dr: Оцінка очікуваних розмірів баз даних може бути значно більше, ніж це прийнято вважати спочатку.


Девід - дуже дякую за детальну відповідь! Я зараз аналізую db, і ваші, і відповіді Кеннета були дуже корисними в моєму розумінні факторів, що впливають на розмір бази даних. Я завжди переймаюся ефективністю (як стосовно прийому даних, так і з використанням даних), а інформація, яку ви надали, була безцінною!
Andrija_Bgd

6

Спробуйте запустити sp_spaceusedсвою базу даних. Як приклад він повертає:

reserved           data               index_size         unused
------------------ ------------------ ------------------ ------------------
6032 KB            2624 KB            1664 KB            1744 KB

Щоб запустити його в базі даних просто USEбаза даних, потім запустіть sp_spaceused.

Якщо вона все ще показує велику кількість невикористаного простору, ви можете спробувати зменшити ще раз. Іноді я виявляю, що потрібно кілька спроб. Також іноді я вважаю, що найкраще працює для зменшення індивідуального файлу, а не для бази даних в цілому. Однак ви можете виявити, що у вас є 2,9 Тб даних та ще 4 + Тб індексів, і в цьому випадку 7,5 ТБ є досить розумним. Якщо ви хочете отримати уявлення про кількість місця (даних та індексу) кожної таблиці, ви також можете запустити sp_spaceusedна рівні таблиці. Ви можете запустити його в усіх таблицях бази даних, використовуючи таку команду:

EXEC sp_msforeachtable 'EXEC sp_spaceused [?];'

Хоча справедливе попередження sp_msforeachtable є недокументованим, непідтримуваним і, як відомо, не вистачає таблиць. З іншого боку, я мав із собою неабияку удачу.

Незважаючи на те, що у вашій базі даних ПОТРІБНО є певний відсоток вільного місця залежно від очікуваного зростання. По суті, ви хочете переконатися, що у вас є місця для зростання від 6 місяців до двох років. Також ви хочете перевірити свої autogrowthнастройки, щоб переконатися, що вони відповідають вашій ситуації. Зокрема, враховуючи розмір вашої бази даних, ви НЕ хочете використовувати% autogrowth.


Дякую! Я використав sp_spaceused, і схоже, що фактичні дані насправді займають вказаний обсяг простору, як це не дивно, як це може звучати для мене, враховуючи фактичний розмір завантажених плоских файлів ... Показники невеликі (у мене немає " t створив будь-які додаткові, оскільки вони були б більше перешкодою, ніж допомогою в моєму випадку), тому я гадаю, що це просто великі фактичні таблиці ... Дякую мільйон за вашу допомогу!
Andrija_Bgd

Бази даних займають більше місця, ніж плоскі файли. Існує певна кількість накладних витрат для структур рядків і таблиць і певна кількість відходів через структуру сторінки.
Кеннет Фішер

-1

Використовуючи SQL Management Studio, 1.Right Клацніть на базі даних, потім 2. Клацніть на завдання-> Зменшити -> Файли

Ви побачите діалогове вікно, яке показує: a. В даний час виділений простір b. Вільне місце + (% безкоштовно)

Якщо ваш% Free перевищує 50%, ви можете розглянути можливість зменшення файлу. Я бачив цей удар аж на 90%. Якщо я вирішу скоротити файл, я зазвичай встановлюю його на 2 або 3 гіга більше, ніж на поточний відведений простір. Більшість моїх баз даних менше 50 гігів. Отже, якщо у вас значно більший файл, то ви можете зробити його на 10 гігів. Я, як правило, переживаю лише про скорочення, якщо я збираюся перенести базу даних на інший сервер, ви можете прочитати все про проблеми, що скорочуються, на будь-якій сторінці sql.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.