Sziasztok!
Nemrég esett meg velem, hogy egy syslog file 1 napnyi tartalmát importálni kellett MsSqlbe. Létre is jött egy szerény 5.000.000 darab rekordot tartalmzó import nevű tábla, ami ugye tartalmazott kőkemény 1 db oszlopot, ami egy valami-string típusú volt.
Aki még nem játszott sysloggal: Egy hatalmas,hosszú stringben tárolja el az összes adatot, amit megkapott valamilyen szolgáltatástól (pl Ips) Tehát ugyanabban a stringben fogod látni a dátumot, időt, forrás ip, cél ip, stbstb adatokat. Ugye milyen elegáns?
Szóval, gyorsan kiegészítettem egy id mezővel az import táblát, hogy mégis legyen egy clusterelt index is a családban. (Egyszer úgy kipróbálnám milyen jó játék lehet egy sok gigás adatbázist HEAP struktúrával üzemelteteni :) )
Ezután futtatam egy ideig a scriptem, amit string-cincáló tárolt eljárásnak neveztem csak el.
(Egy ideig = Egy tisztességes adag amerikai kávét simán elkortyolgattam, mire végzett, dehát érthető is)
Ekkor már megvolt a cél táblám, ami tartalmazott mindenféle ID-t, forrás és cél ip címeket, dátumot, és más egyéb okosságokat.
Már kezdett megfogalmazódni bennem az "ez is megvan, még sincs este" szlogen amit egy cimborámtól szoktam volt kölcsönvenni, amikor megkopoktatták a vállamat, hogy ugyanmár, miért van a rekordok majd' felénél többszöröződés? Mint kiderült, a syslog is így kapta már meg az adatokat, noha ez engem nem vígasztalt, mivel a táblám így nem a valóságot tartalmazza...
Tehát most több millió rekordot nyálazzak át, hogy miben van egy, és miből több...
Eddig a prológus.
Mivel az első google találatok szvsz agyonbonyolított subkveris megoldásokkal akartak segíteni, inkább erőt vettem magamon, és nekiálltam gondolkodni.
Hogyan kellene kitörölni?
1.: Számoljuk meg hogy az X db mezők alapján hány egyforma rekord van.
2.: Ezt irassuk ki a táblával
3.: Ha ez a mennyiség több, mint 1, akkor törlés
Ahhoz hogy ez átlátható legyen, ja és nem mellesleg hatékony Execution Plannel működjön a CTE mellett voksoltam.
Íme:
with cte_tobb_azonos_rekord_torlese
as
(
select row_number() over(partition by source_ip,dest_ip,datum order by source_ip) as sorszam,
source_ip,dest_ip,datum
from adatbázis.dbo.táblám
)
delete from cte_tobb_azonos_rekord_torlese
where sorszam>1
Sziasztok!
Jó munkát! :)
Ügyes megoldás! :)
VálaszTörlésÉn is szeretem a CTE-ket, és ez +1 okos érv mellettük.
Köszi :)
VálaszTörlésIgen, emlékszem, hogy a query tanfon is sok mindent CTE-vel csináltál :)