Zistenie veľkosti dát vo všetkých tabuľkách v databáze

Publikoval Michal Kočí dňa 26.11.2006 o 16:09 v kategórii SQL

Pozná to snáď každý, systém sa vyvine, otestuje sa a odovzdá sa. Dodávateľ dostane zaplatené, zákazník systém používa a je viac či menej spokojný. Po čase však môže nastať s aplikáciou problém, pretože sa počas vývoja na niečo nemyslelo. Aplikácia je čím ďalej pomalšia, zákazník nespokojnejší. Následne by mal dodávateľ spraviť akúsi profylaktiku systému - zistiť, prečo je systém pomalý. Jedným z dôvodov môže byť veľké množstvo dát v niektorej z tabuľiek, pričom sa vopred s takým množstvom dát nerátalo. Spravil som malý SQL skript, ktorý vylistuje zoznam tabuliek v databáze a u každej zobrazí počet riadkov a veľkosť v kilobytoch, ktorú tabuľka zaberá.

Celý skript je jednoduchý, v zásade celú prácu necháva na dve uložené procedúry Microsoft SQL Servera:

  • Prvá použitá procedúra je sp_spaceused. Táto vracia dátovú množinu, ktorá obsahuje nami spracovávané údaje, t.j. najmä názov tabuľky, počet riadkov a veľkosť v kilobytoch.
  • Druhou procedúrou je nedokumentovaná procedúra sp_msforeachtable. Patrí k sade zaujímavých nedokumentovaných procedúr a slúži na vykonanie nejakého SQL príkazu pre nad každou tabuľkou v databáze.

Skript funguje nasledovne: Keďže uložená procedúra sp_spaceused vracia dátovú množinu, s touto je možné rozumne pracovať iba ak si jej výsledky uložíme do tabuľky. Preto ako prvý krok skriptu vytvoríme tabuľku, ktorá sa snaží kopírovať štruktúru výslednej množiny. Bohužial, uvedená procedúra vracia niektoré zaujímavé dáta nie v celočíselnom formáte ale v textovom formáte. Preto si vytvoríme ešte jednu pomocnú tabuľku, ktorá už bude obsahovať dáta so správnym dátovým typom:

create table #spaceused
(
    name varchar(64),
    rows int,
    reserved varchar(16),
    data varchar(16),
    index_size varchar(16),
    unused varchar(16)
)
 
create table #spaceused2
(
    name varchar(64),
    rows int,
    reserved int,
    data int,
    index_size int,
    unused int
)

Ďaľším krokom musí byť zavolanie procedúry sp_msforeachtable. Tej predáme pomocou parametra @command1 SQL príkaz, ktorý chceme spustiť nad každou tabuľkou, pričom namiesto názvu tabuľky sa u procedúry sp_msforeachtable používa zástupný znak otáznik (?). Keďže nad každou tabuľkou chceme spustiť ako príkaz zavolanie procedúry sp_spaceused pričom výslednú sadu chceme pridať ako záznam do tabuľky #spaceused, príkaz bude vyzerať nasledovne:

exec sp_msforeachtable @command1="insert into #spaceused exec sp_spaceused '?'"

Fajn, požadované dáta už máme v tabuľke #spaceused, ale ešte nie sú v tabuľke #spaceused2. V tejto ich potrebujeme mať z veľmi prozaického dôvodu. Obvykle nás totiž zaujíma niektorý konrétny údaj, napríklad počet riadkov a podľa neho chceme výsledné dáta zoradiť. To ale nie je možné, ak sú dáta v textovom formáte. Takže si dáta jedným príkazom preklopíme:

insert
into    #spaceused2
select    name,
        rows,
        left(reserved, len(reserved) - 3),
        left(data, len(data) - 3),
        left(index_size, len(index_size) - 3),
        left(unused, len(unused) - 3)
from    #spaceused

Ostávajú už len dve posledné veci. Prvá je samotný výber dát z tabuľky a zoradenie si výsledku podľa našich požiadaviek:

select        *
from        #spaceused2
order by    4 desc

A druhá a posledná je odstránenie dočasných tabuliek:

drop table #spaceused
drop table #spaceused2

Celý skript potom vyzerá takto:

create table #spaceused
(
    name varchar(64),
    rows int,
    reserved varchar(16),
    data varchar(16),
    index_size varchar(16),
    unused varchar(16)
)
 
create table #spaceused2
(
    name varchar(64),
    rows int,
    reserved int,
    data int,
    index_size int,
    unused int
)
 
 
exec sp_msforeachtable @command1="insert into #spaceused exec sp_spaceused '?'" 
 
 
insert
into    #spaceused2
select    name,
        rows,
        left(reserved, len(reserved) - 3),
        left(data, len(data) - 3),
        left(index_size, len(index_size) - 3),
        left(unused, len(unused) - 3)
from    #spaceused
 
 
select        *
from        #spaceused2
order by    4 desc
 
 
drop table #spaceused
drop table #spaceused2

Na záver už len malá poznámka, ktorá by sa možno hodila hneď na začiatok - skript je funkčný aj na SQL Serveri 2000 aj na SQL Serveri 2005.

Mohlo by ťa tiež zaujímať

Páčil sa ti príspevok?

Zdieľaj príspevok alebo si ho odlož na neskôr

Sleduj ma

Ak nechceš premeškať príspevky ako je tento, sleduj ma na Twitteri, alebo ak máš RSS čítačku, môžeš sledovať môj RSS kanál.

Komentáre

K tomuto článku nie su pridané žiadne komentáre.

Pridať komentár

Máš niečo zaujímavé povedať k článku? Pridaj to k článku ako komentár. Spam, reklamu alebo inak nerelevantné komentáre okamžite mažem.