.NET in velika količina podatkov v bazi
11 naročnikov
11 naročnikov
V SQL (Firebird SQL) bazi imam 3 tabele: Product (podatki o izdelkih), Property (možne lastnosti izdelkov) in Product_Property (lastnosti posameznih izdelkov, vmesna tabela)
Trenutno skupaj sestavljam filter (.NET web forms), ki bo na podlagi izbranih lastnosti vrnil spisek izdelkov, ki ustreza kriteriju. Do te točke je vse fine and dandy.
Problem pa se pojavi pri scenariju, ko gre za ogromno bazo: cca 200k izdelkov (Product), 40k lastnosti (Property) in približno 8 mio lastnosti izdelkov (Product_Property). Samo filtriranje traja precej predolgo, če program že vmes ne odleti zaradi premalo pomnilnika.
Ima kdo kakšen namig, izkušnjo, karkoli kako se te zadeve lotit? Kot že rečeno, gre za FirebirdSql bazo, na katero se .NET aplikacija poveže s pomočjo Firebird.NET providerja.
Hvala!
p.s.: Ker gre za integracijo na obstoječ sistem, bilokakšna prekopavanja baze ne pridejo v poštev. Lahko se doda kakšna zadeva, obstoječih tabel pa se ne sme dotikat.
22 odgovorov
Nazadnje sem srečal Firebird SQL pri Vascotu. Žal pa ti ne znam pomagat v okviru zgoraj navedenih tehnologij.
Če bi jaz delal s tem, bi bazo z avtomatiko zgolj kopiral v kakšno drugo enkrat dnevno in svojo rešitev sestavil čim dlje stran od .NET ;)
Na kakšen način bi pa v "ne .NET" tehnologiji obdeloval takšne količine podatkov? V katerem jeziku oz. skripto, na kakšen način? Mislim, da je tole lahko precej splošen problem in ni (toliko) omejen na tehnologijo.
Aja, pa gre za web aplikacijo (integracijo), torej so performance, cache, ipd. seveda hudo pomembne zadeve. Še več: ker imajo različne stranke lahko različne cene (B2B in B2C), se le te izračunajo ob branju iz baze in nato hranijo v cache-u.
Pa še offtopic: ne bi se zdej spuščal v debate za/proti .NET :) Ker, ko se kakšna brihta oglasi, kako je PHP (al pa bognedaj Java) boljša od njega, ga sploh ne jemljem kot resnega sogovornika :) Pa ne zato, ker bi imel kaj proti opisanim jezikom, ampak čim nekdo favorizira neko tehnologijo, vse druge pa proglasi za neuporabne, je to zame znak omejenega mindseta. Vsakemu (developerju ali pa projektu) svoje. Ampak ta komentar kar zaključimo tu, ker me zanima bilokakšna rešitev opisanega problema.
Update: Sem si malo gledal zdaj o Firebird bazi, baje je kar scalable. Tako da kar se velikosti baze tiče, to sploh ne bi smel bit problem.
Je pa seveda odvisno od obstoječe rešitve, kako so tabele optimizirane. Če se baze ne smeš dotikat, jo lahko kopiraš v svojo 1x dnevno, ki jo lahko optimiziraš po svoje ter vse querije izvajaš na lastni optimizirani kopiji baze.
.NET pa meni ni všeč, ker vse deluje počasi in rabi trikrat preveč resursov. Ne izključujem pa možnosti, da sem dobil tak vtis zaradi slabih .Net programerjev. :)
Najprej si naredi kopijo baze, jo pusti tako kot je, vendar naj bo ločena od delovne baze.
Potem sestavi par testnih querijev in si zabeleži čas, ki ga query porabi. Nato čim več testiraj...
A ti povem eno še počasnejšo? :)
Izberi določene propertyje in probaj preštet koliko izdelkov ustreza drugim še ne izbranim propertyjem (na tvoji količini podatkov)
S toliko podatki podobnih stvari še nisem delal, ampak pomojem moraš podatke najprej spravit npr. v temporary pivot tabelo, ampak ker imaš miljone propertyjev si omejen s št. stolpcev,....
Kaj drugega, kot da podatke zapišeš v neko no sql bazo (npr mongo) ne vidim.
Jaz bi sigurno probal, prepisal podatke v mongota in tam testiral.... Vsaj izognil se boš "miljon" joinom.
Prosim obveščaj kako napreduješ ker me zelo zanima.
Drugače pa čakam, da Vini pove kakšno pametno ;)
edit: typo
jazzfunk:
.NET pa meni ni všeč, ker vse deluje počasi in rabi trikrat preveč resursov. Ne izključujem pa možnosti, da sem dobil tak vtis zaradi slabih .Net programerjev. :)
To ni ravno tako, "vse deluje počasi in rabi 3x preveč resursov". Če je stvar narejena, kot je treba, ni res. Sicer kar razumem trenutni problem, je bottleneck na bazi, ne v .NETu.
Po drugi strani pa imaš Magento, ki ti "požre boga in pol" od resursov.
PS: Da ne bo pomote, delam oboje (.NET in razne PHP zadeve, razni frameworki).
Ah, pomanjkljive informacije.
Tale web aplikacija zaradi drugih funkcionalnosti že drži v cache-u podatke o izdelkih (za prikazovanje) in lastnostih (za generiranje obrazca za filtriranje) - v obliki DataTable objekta. Dodaten razlog za to je tudi podpora za B2B (kjer imajo lahko različni uporabniki različne rabate, torej se cene izračunajo sproti, pri branju iz baze)
Bottleneck tukaj je sam postopek v aplikaciji, ko je treba prikazat izdelke, ki ustrezajo filtru. Trenutno je zadeva takšna: ko so pogoji nastavljeni, dobim idje vseh izbranih lastnosti (property). Potem iz tabele Product_Property (iz baze, ker 8 mio zapisov hranit v cache-u je ogromno) preberem vse idje izdelkov, ki ustrezajo tem lastnostim. Na podlagi idjev izdelkov pa nato (iz cache-a) izpišem ustrezne izdelke. Kako čimbolj optimalno narest ta postopek? Stvar sicer deluje, ampak ne pri takšni količini podatkov :)
Kopiranje baze pa zaradi integritete podatkov tudi ne pride v poštev (podatki se lahko spreminjajo iz minute v minuto, ali pa samo enkrat na dan). Moram pa se pozanimat, kako je z dodajanjem indeksov na obstoječe tabele. Žal (zaradi obstoječe rešitve) obstajajo določene omejitve oz. omejen manevrski prostor :)
Vsem dosedanjim komentatorjem pa najlepša hvala! Seveda so kakršnikoli drugi namigi še vedno več kot dobrodošli :)
Pomojem je problem, ker potrbuješ pri branju iz tabele Product_Property za vsako izbrano lastnost dodaten join. Verjetno se zadeva upočasni šele, ko je izbranih več lastnosti ali že pri prvi?
Baje ima Firebird "PLAN analyzer", ki deluje podobno kot EXPLAIN v mysqlu.
Preveri kako je z indexi, konfiguracijo baze, koliko ram-a lahko uporablja za hranjenje indexov itd...