[MSSQL] Dane binarne i rozrost bazy

0

Cześć,

Posiadam kolumnę w jednej z tabel typu varbinary(max). Przyjmijmy, że na tę chwilę jest to jedyne wyjście, aby dane te były bezpośrednio w bazie.

Mój problem polega na nielogicznie szybkim wzroście rozmiarów bazy danych (pliku *.mdf oraz loga *.ldf). Władowałem do bazy 30 rekordów z birnakami po 2MB każdy a moja baza rozrosła się przez to do 2GB (suma rozmiaru mdf i ldf).

  1. Jaka jest tego przyczyna? Dlaczego tak się dzieje?
  2. Czy to wynika z jakiś ustawień bazy danych, które można zmienić ?

Dzieki za pomoc.

0

Log nie liczy sie do rozmiaru bazy danych. W pierwszej kolejnosci policz rozmiary tabel w bazie danych i skonfrontuj z rozmiarem samej bazy (mdf). Przy tworzeniu bazy danych ustawiales zapewne skok przyrostu bazy w przypadku koniecznosci zwiekszenia rozmiaru - moze jest za duzy? Sprobuj tez wykonac shrink na bazie i zobacz czy wtedy rozmiar odpowiada przechowywanym danym. Dodatkowo mozesz obciac log transakcyjny (TRUNCATE LOG).

0

Przyrost jest ustawiony na 3MB. Shrink niestety nie zmniejsza rozmiaru jeśli dane się tam znajdują (dopiero po ich wywaleniu i użyciu tego polecenia baza wraca do normalnych rozmiarów). Rozmiar tabel raczej nie ma wpływu, gdyż dla testów "baza" składa się tylko z tej jednej tabeli.

W jakiej formie dane są przesyłane po sieci z serwera SQL do klienta? Jest to jakiś mocno wyspecyfikowany i wydajny sposób? Bo jeśli problem się nie rozwiąże, to dane binarne będę dopisywał do 1 pliku na serwerze za pomocą strumienia i potem odczytywał obliczone fragmenty tego pliku, ale mam wrażenie, że będzie to działało wolniej i to znacznie.

0

masz tu skrypt, ktory wypisze ci wielkosc danych, indexu, zarezerwowane miejsce dla tabeli oraz ile miejsca jest nieuzywane

na razie daruj sobie zglebianie przyczyn wielkosci loga, znajdz przyczyne rozrastania sie samego pliku danych
a swoja droga jesli wrzucasz 2MB pliki, a shrink jest na 3MB to troche slaby pomysl, lepiej ustaw skok co 8 czy nawet 16MB

BEGIN try  
DECLARE @table_name VARCHAR(500) ;  
DECLARE @schema_name VARCHAR(500) ;  
DECLARE @tab1 TABLE( 
        tablename VARCHAR (500) collate database_default 
,       schemaname VARCHAR(500) collate database_default 
);  
DECLARE  @temp_table TABLE (     
        tablename sysname 
,       row_count INT 
,       reserved VARCHAR(50) collate database_default 
,       data VARCHAR(50) collate database_default 
,       index_size VARCHAR(50) collate database_default 
,       unused VARCHAR(50) collate database_default  
);  
 
INSERT INTO @tab1  
SELECT t1.name 
,       t2.name  
FROM sys.tables t1  
INNER JOIN sys.schemas t2 ON ( t1.schema_id = t2.schema_id );    
 
DECLARE c1 CURSOR FOR  
SELECT t2.name + '.' + t1.name   
FROM sys.tables t1  
INNER JOIN sys.schemas t2 ON ( t1.schema_id = t2.schema_id );    
 
OPEN c1;  
FETCH NEXT FROM c1 INTO @table_name; 
WHILE @@FETCH_STATUS = 0  
BEGIN   
        SET @table_name = REPLACE(@table_name, '[','');  
        SET @table_name = REPLACE(@table_name, ']','');  
 
        -- make sure the object exists before calling sp_spacedused 
        IF EXISTS(SELECT OBJECT_ID FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(@table_name)) 
        BEGIN 
                INSERT INTO @temp_table EXEC sp_spaceused @table_name, false ; 
        END 
         
        FETCH NEXT FROM c1 INTO @table_name;  
END;  
CLOSE c1;  
DEALLOCATE c1;  

	SELECT t1.*, t2.schemaname  
	FROM @temp_table t1  
	INNER JOIN @tab1 t2 ON (t1.tablename = t2.tablename ) 
	--ORDER BY  schemaname,tablename
	union all
	select '<Total size>', null, cast(sum(cast(replace(reserved, ' KB','') as int)) as nvarchar(100))+' KB',null,null,null,null from @temp_table

END try  
BEGIN catch  
SELECT -100 AS l1 
,       ERROR_NUMBER() AS tablename 
,       ERROR_SEVERITY() AS row_count 
,       ERROR_STATE() AS reserved 
,       ERROR_MESSAGE() AS data 
,       1 AS index_size, 1 AS unused, 1 AS schemaname  
END catch

1 użytkowników online, w tym zalogowanych: 0, gości: 1