powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Очистка BLOB полей в большой таблице
11 сообщений из 11, страница 1 из 1
Очистка BLOB полей в большой таблице
    #39755647
Alexander Us
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, нужен совет экспертов:

SQL: Microsoft SQL Server 2008 (SP4) - 10.0.6000.29 (X64) ; Enterprise Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: )

Есть большая таблица в режиме 7х24, с 3 BLOB полями.
В неё идет интенсивная запись, 10 - 300 строк в секунду.
По ночам стартует процесс очистки, который страсывает блоб поля для запиcей старше Х дней в NULL.
Некоторые блоб поля для некоторых строк остаются несброшенными.
Проблема в том, что этом место, занятое блобами очищается не полностью.

В результате приходится периодически перезаливать всю таблицу, и таблица становится в 8-10 раз меньше!
Например сейчас таблица весит 2,6 ТБ, после перезаливки 0,26 ТБ:
TabRowsCntReservedMBDataMBPagesCntindex_sizeMBunusedMBдо перезаливки53376923026206352541191325272474728926551после перезаливки5268295482613281968892520187963934504 (разницу в количестве строк пожалуйста игнорируйте)

Есть ли идеи, как тожно очищать блоб поля без необходитости "ручной" перезаливки?

PS:
Что приходит в голову:
Приделать к таблице поле "Cleaned" и партиционировать таблицу по нему.
При очиске блоб полей устанавливать Cleaned=1, в надежде, что это повлечёт перемещение записей в другую партицию - т.е. как бы неявную перезаливку.
Будет ли такой трюк работать?

Структура таблицы:

Таблица:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
CREATE TABLE [dbo].BlobTable
(
	[Col_PK] [int] IDENTITY(1,1) NOT NULL,
	[Col_ParentValue] [int] NULL, 
	[Col03] [varchar](100) NULL,
	[Col04] [int] NULL,
	[Col05] [varchar](200) NULL,
	[Col06] [smallint] NULL,
	[Col07] [smallint] NULL,
	[Col08] [smallint] NULL,
	[Col09] [smallint] NULL,
	[Col10] [int] NULL,
	[Col11] [int] NULL,
	[Col12] [int] NULL,
	[Col13] [varchar](255) NULL,
	[Col14] [varbinary](max) NULL,
	[Col15] [varbinary](max) NULL,
	[Col16] [varbinary](max) NULL,
 CONSTRAINT [PK_BlobTable] PRIMARY KEY CLUSTERED ([Col_PK])
) 
-- есть ещё несколько индексов, которые я не привожу для экономии места. 




Измерения:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
CREATE view [dbo].[v_TableSpaceUsage] 
as
-- from sp_spaceusage
select 
[Schema_Name],
Table_Name,
[rowCount] as RowsCnt,
cast((reservedpages * 8) / 1024.0 as decimal(18,1))  as ReservedMB,  
cast((pages * 8) / 1024.0 as decimal(18,1)) as DataMB,
pages as PagesCnt,
index_sizeMB =  cast((CASE WHEN usedpages     > pages     THEN (usedpages - pages)         ELSE 0 END * 8) / 1024.0 as decimal(18,1)),
unusedMB =      cast((CASE WHEN reservedpages > usedpages THEN (reservedpages - usedpages) ELSE 0 END * 8) / 1024.0as decimal(18,1))

from
( 
 SELECT 
        s.name as [Schema_Name],
        object_name(p.object_id) Table_Name,
		reservedpages = SUM (reserved_page_count),
		usedpages = SUM (used_page_count),
		pages = 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
			),
		[rowCount] = SUM (
			CASE
				WHEN (index_id < 2) THEN row_count
				ELSE 0
			END
			)
	FROM sys.dm_db_partition_stats p
	join sys.objects o on p.object_id=o.object_id and o.type in ('U') 
	join sys.schemas s on o.schema_id=s.schema_id
	group  by  s.name, p.object_id
 )T


...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755663
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
alter index PK_BlobTable on dbo.BlobTable reorganize with (lob_compaction = on);
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755664
Dzianis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alexander Us,

а как реагирует на шринк и реорганизация индексов?
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755671
Alexander Us
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

спасибо, на днях попобую.
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755682
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander Us,

Может оказаться, что перелить в новую таблицу с минимальным журналированием будет гораздо эффективнее.
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755687
Alexander Us
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmМожет оказаться, что перелить в новую таблицу с минимальным журналированием будет гораздо эффективнее.
Переливаю своим тулом на основе SqlBilkCopy, база в Simple Mode. (минимальне журналирование, или?)

Проблема в том, что такую переливку приходится выполнять вручную:
перелить из BlobTable в BlobTable_NEW, а затем "переключить" таблицы.

Недостатки метода:
- для переключения старой и новой таблиц приходится выбирать окно с минимальной загрузкой
- переключение приходиться выполнять вручную, на мой взгляд овтоматизировать рискованно
- старая и новая таблицы, обе лежат в базе и занимают место

Что касается reorganize with (lob_compaction = on), много лет назад я пробовал его на SQL 2005, тогда эффекта не было.
Но думаю, имеет смысл попробовать ещё раз, на SQL 2008.

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

Как Вы думаете, трюк с партиционированием может дать желаемое?
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755772
Rankatan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как насчет варианта вынести блобы в отдельную таблицу? Связь 1 к 1, дальше секционирование этой таблицы, очистку делать с помощью truncate partitions (в sql 2008 switch+trunctate)
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755773
Фотография Relic Hunter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно вообще в FILESTREAM хранить.
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755804
Alexander Us
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RankatanКак насчет варианта вынести блобы в отдельную таблицу? Связь 1 к 1, дальше секционирование этой таблицы, очистку делать с помощью truncate partitions (в sql 2008 switch+trunctate) Удалять надо не стороки, а данные в ячейках таблицы - выборочно.
Кроме того, в таблицу постоянно идут вставки, и для switch+trunctate наверное нужно будет определять окна обслуживания - т.е. выводить таблицу в оффлайн.
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755807
Alexander Us
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Relic HunterА можно вообще в FILESTREAM хранить.
Можно, но нужно ли:
Средняя длинна всех трёх блоб полей 6КБ (есть исключения, поэтому длиння полей установлена в max).
А рекомендуемая длинна поля для FILESTREAM от 1МБ?
...
Рейтинг: 0 / 0
Очистка BLOB полей в большой таблице
    #39755819
Mr. X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alexander Us,

Для switch нужна монопольная блокировка на таблицу источник, но она длится доли секунды. Это и будет вашь downtime.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Очистка BLOB полей в большой таблице
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]