Размер одной записи? SQL

У меня есть сценарий, в котором каждому пользователю было выделено 2 МБ места в базе данных. Теперь я должен показать процент использования выделенного пространства, для этого мне нужно знать размер одной записи в таблице.

Я пытался использовать sp_spaceused и даже написал собственную процедуру с использованием длины данных ... но они показывают огромную разницу в своих результатах.

Есть ли способ сделать это правильно.


person Community    schedule 21.04.2009    source источник
comment
Для чего используется это пространство?   -  person Anton Gogolev    schedule 21.04.2009
comment
Как вы разделяете свои пользовательские данные? Это все в одной таблице? Или у каждого пользователя свои таблицы?   -  person Eoin Campbell    schedule 21.04.2009
comment
У меня есть одна таблица, в которой сохраняются все пользовательские данные. UserId используется для различения данных отдельных пользователей.   -  person    schedule 21.04.2009
comment
@Sandhurts: что вы считаете пользовательскими данными? Вся запись в вашей таблице? Только один столбец этой таблицы? Должен ли индекс в этой таблице учитываться как пользовательские данные?   -  person Lieven Keersmaekers    schedule 21.04.2009
comment
вся запись для этого пользователя в таблице, а также индекс содержит пользовательские данные   -  person    schedule 21.04.2009
comment
Таким образом, оптимизировав вашу таблицу, добавив индексы, пользователи могут превысить свое распределение?! Если вы показываете процент использования своим пользователям, это может стать очень запутанным.   -  person Lieven Keersmaekers    schedule 21.04.2009
comment
возможно, покажите нам свою попытку и спросите, что можно сделать, чтобы улучшить ее или найти проблему, почему она не дает хороших результатов.   -  person KM.    schedule 21.04.2009
comment
Я думаю, к сожалению, реальность такова, что нет хорошего ответа на ваш вопрос, поскольку он относится к вашей конкретной проблеме. Причина в том, что даже если вы определили фактическое пространство данных, потребляемое каждой строкой, связали каждую из этих строк с пользователем, а затем определили, какие из этих строк принадлежат каким страницам данных, вы не достигнете 100% точности. Результаты всегда будут в лучшем случае нечеткими, поскольку всегда есть некоторая потеря разрешения из-за того, как работает механизм хранения. Возможно, пришло время рассмотреть альтернативный метод реализации ваших квот, например количество строк.   -  person The Lazy DBA    schedule 12.05.2009


Ответы (5)


Запустите DBCC SHOWCONTIG с именем вашей таблицы.

dbcc showcontig ('TableName') with tableresults

затем посмотрите на максимальный минимальный и средний размер записи

person SQLMenace    schedule 21.04.2009
comment
какова единица этих размеров, которые вы упомянули, они КБ или Б - person semirturgay; 25.04.2014
comment
msdn.microsoft.com/en-us/library/ms175008.aspx - Глядя на это, я считаю, что это байты - person JsonStatham; 25.02.2015
comment
К вашему сведению, согласно связанной странице MSDN: эта функция будет удалена в будущей версии Microsoft SQL Server. Не используйте эту функцию в новых разработках и как можно скорее измените приложения, которые в настоящее время используют эту функцию. Вместо этого используйте sys.dm_db_index_physical_stats. - person DaveD; 28.05.2015
comment
Когда я сравниваю результаты этого с измерениями записей с использованием длины данных (например, dba.stackexchange.com/a/25532/24058 ), я получаю очень разные ответы для минут и максимумов. datalength учитывает длину данных var(max) , которая является LOB, поэтому, возможно, не должна учитываться в зависимости от того, что хочет OP. однако минимальная сумма длин данных намного меньше, чем минимальная, заданная DBCC SHOWCONTIG. - person user420667; 13.10.2016

Следующий запрос сообщит вам процент @SpaceAllotted, который используется данными, посмотрев, сколько страниц выделено объектами базы данных.

Не стоит пытаться измерять использование на уровне строк, поскольку SQL Server выделяет все пространство на уровне экстентов. Каждый экстент состоит из восьми страниц данных по 8 КБ. Таким образом, если в вашей базе данных была только одна строка, и эта строка содержала 4 байта данных, все равно нужно было бы выделить весь экстент для хранения этих 4 байтов (или использовать существующий экстент с нераспределенными страницами. Это называется смешанным экстентом). ).

DECLARE @SpaceAllotted      FLOAT
-- 2MB converted to kilobytes...
SET     @SpaceAllotted = 2048

SELECT 
    -- Allocation is done on the extent-level.
    -- Each extent contains eight 8KB data pages.
    ((1 / (@SpaceAllotted)) * CEILING(CAST(SUM([ips].[page_count]) AS FLOAT) / 8) * 64) * 100 AS PercentageUsed
FROM
    [sys].[dm_db_index_physical_stats](DB_ID(), NULL, NULL, NULL, NULL) ips
    -- This will allow us to retrieve the page count of all tables in the
    -- current database, regardless of whether or not they have clustered
    -- indexes and/or non-clustered indexes.
INNER JOIN
    [sys].[indexes] i
    ON
        [ips].[object_id] = [i].[object_id]
    AND [ips].[index_id] = [i].[index_id]

Поскольку у нас есть возможность смешанных экстентов и нет хорошего способа (способы есть, но они не будут красивыми) определения того, какие страницы и каким экстентам отведены, это не так. 100% точно. Кроме того, экстенты могут даже иметь свободные страницы (которые зарезервированы и, следовательно, все еще занимают место на диске), поэтому обычно эта оценка всегда будет низкой. Тем не менее, это, вероятно, лучшее, что вы получите, не написав что-нибудь для проверки базы данных на уровне страницы.

Ах да, глядя на другие ответы, это еще один вариант. Это в основном будет смотреть на все текущие размеры файлов данных на страницах и определять процент пространства, которое они потребляют. Тут тоже есть оговорки...

  • Если для базы данных не указан максимальный размер (автоматическое увеличение включено и не ограничено), это не сработает, поскольку max_size будет возвращено как -1.
  • Опять же, мы не можем точно определить, сколько места занимают фактические данные. Здесь мы смотрим, сколько места фактически используется в файловой системе.
  • Мы не смотрим на пространство файла журнала. Да, это по-прежнему занимает место на диске.

Надеюсь, что один из них решит вашу проблему.

SELECT 
    ((1 / CAST(SUM([df].[max_size]) AS FLOAT)) * CAST(SUM([df].[size]) AS FLOAT)) * 100 AS PercentUsed
FROM 
    [sys].dm_io_virtual_file_stats(DB_ID(), NULL)   vfs
INNER JOIN 
    [sys].[database_files]  df
    ON 
        [vfs].[file_id] = [df].[file_id]
WHERE 
    [df].[type] = 0
person The Lazy DBA    schedule 11.05.2009

Поскольку showcontig будет объявлен устаревшим, вы также можете использовать:

SELECT * FROM sys.dm_db_index_physical_stats
(DB_ID(N'DatabaseName'), OBJECT_ID(N'TableName'), NULL, NULL , 'DETAILED')
person Glade Mellor    schedule 26.09.2012

Вы можете рассчитать размер строки (количества строк) с помощью довольно сложной формулы. См. книги в Интернете (ms-help://MS.SQLCC.v9). /MS.SQLSVR.v9.en/udb9/html/81fd5ec9-ce0f-4c2c-8ba0-6c483cea6c75.htm) для получения более подробной информации.

Короче говоря:

Возьмите количество столбцов и определите размер каждого столбца по его типу данных для типов данных фиксированной длины.

Рассчитайте пространство, используемое для любых столбцов, допускающих значение NULL. Затем рассчитайте пространство строк:

Row_Size = Fixed_Data_Size + Variable_Data_Size + Null_Bitmap + 4

person edosoft    schedule 21.04.2009

Данные сохраняются на диске в каталогах, названных в честь базы данных. Это включает в себя все, включая то, что вы не измеряете (индексы и т. д.). Измерьте это.

person tpdi    schedule 21.04.2009
comment
Как их измерить, любая подсказка будет полезна - person ; 21.04.2009