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:
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.
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.