SQL baze podataka - Sponzor: Baze-Podataka.net MySQL, MSSQL, Oracle, Access, ODBC. Ako imate problem brže i preciznije ćete dobiti odgovor ako priložite strukturu tabela ili skript koji kreira tabele i puni ih test podacima umesto što to problem opisujete samo rečima. Sponzor: Baze-Podataka.net - Blog o bazama podataka |
|
Alati teme | Način prikaza |
15. 06. 2012. | #1 |
Super Moderator
Knowledge base
Datum učlanjenja: 02.10.2006
Lokacija: Niš
Poruke: 1.618
Hvala: 263
275 "Hvala" u 104 poruka
|
Dizajn search baze podataka?
Oh well...
To sto pisem ovde znaci da sam bas zapao u corsokak Imao sam 'search' na sajtu koji je do sada sa MyISAM tabelama funkcionisao zadovoljavajuce [ili pak ja nisam primetio da se zapucava] Problem je nastao kada sam sve tabele konvertovao u InnoDB No, hajde da se vratimo na pocetak - dizajn tabela: Imamo standardno dve tabele - words-index i positions-of-words. words-index tabela: WordID - naravno unique key Word - unique polje [dakle isto index] positions-of-words tabela: ArticleID - index WordID - index kada se radi pretraga - pokupim WordID-eve od datih reci, i onda ide query: SELECT ArticleID, WordID, COUNT(WordID) AS pogodaka FROM positions-of-words WHERE WordID IN (... spisak WordID-eva...) GROUP BY ArticleID HAVING pogodaka>=4 ORDER by ArticleID DESC LIMIT 0, 12; ova cetvorka gore je broj reci [varira od broja WordID-eva]. sta query radi: - nadje sve ArticleID-eve koji sadrze navedene reci (WordID IN (...)) - grupise ih po ArticleID (GROUP BY ArticleID) - ovo nazivam 'ukrštanje' - generise polje 'pogodaka' koje oznacava koliko je zadatih reci nadjeno u datom zajednickom artiklu (COUNT(WordID) AS pogodaka) - odnosno u ukrstenoj grupi odozgo - odstranjuje sa liste artikle koji ne sadrze sve reci pretrage (HAVING pogodaka>=) sve ovo lepo radi dok neko ne pretrazi rec (WordID) koja se u nalazi u 100.000 artikla - jer to znaci da je i u 'positions-of-words' tabeli ima u 100.000 row-a. I tu stvar zapne - po minut-dva mu treba da pohvata ceo index za datu rec. Jos ako pretrazi dve-tri takve reci u istom upitu - eto ludila. Evidentan problem ovde je taj sto on mora sav index artikla za datu rec da fetchuje - da bi ih ukrstio sa indexom artikla druge reci [trece, cetvrte...] - da bi mogao da nadje zajednicke artikle... To je ogromna kolicina podataka. EXPLAIN daje sledece: Kôd:
+----+-------------+---------------------+-------+---------------+--------------+---------+------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+---------------------+-------+---------------+--------------+---------+------+-------+-------------+ | 1 | SIMPLE | positions-of-words | index | WordID | ArticleID | 4 | NULL | 57691 | Using where | +----+-------------+---------------------+-------+---------------+--------------+---------+------+-------+-------------+ InnoDB je naravno zahtevao da se doda UNIQUE ID KEY u tabeli 'positions-of-words'. Dodao sam, to je ubrzalo stvari malo, bar za manje koriscene reci, ali kod mnogo koriscenih reci i dalje izvrsava upit po par minuta. Buffer pool size je naravno setovan na 70% RAM-a, i ceo index je u RAM memoriji [Buffer pool hit rate 1000 / 1000]. I dalje mi nije jasno zasto se sa MyISAM tabelom ovo sve izvrsavalo za svega par sekundi. Moze li neko bar da mi da neku smernicu - u kom pravcu da kopam. Ako je query los - postoji li neki drugi nacin da 'preklopim' indexe od svake reci u search frazi... ili je ceo koncept los? Poslednja izmena od Peca : 15. 06. 2012. u 14:23. |
15. 06. 2012. | #2 |
Иван Бишевац
Qualified
|
Зашто си мењао из MyISAM у INNO DB?
Први је одличан код упита који углавном читају податке а други је новији и бољи у смислу да подржава интегритет података и бољи је код интензивног уписа података. За поређење погледај: http://www.kavoir.com/2009/09/mysql-...-and-cons.html |
15. 06. 2012. | #3 |
Super Moderator
Knowledge base
Datum učlanjenja: 02.10.2006
Lokacija: Niš
Poruke: 1.618
Hvala: 263
275 "Hvala" u 104 poruka
|
menjao sam da bih izbegao LOCK cele tabele kada se iz nje nesto brise
mislis da je prelazak na InnoDB bila losa ideja? Poslednja izmena od Peca : 15. 06. 2012. u 14:27. |
16. 06. 2012. | #4 | |
Иван Бишевац
Qualified
|
Citat:
Мада као што и сам кажеш претходно ти је радило добро са претрагом, а сада слабо ради, тако да је очигледно погрешан приступ. Ово нема пуно везе са технологијом, не треба ти експерт да ти каже шта је логичније. Можеш ли мало боље да опишеш ситуацију око брисања и закључавања целе табеле, шта је ту био проблем. Јел време које се чека да се операција брисања изврши? Колико је то критично? Ако ти то брисање није толико хитно онда треба да се вратиш на претходно пошто је MyISAM одличан за претраге и Full Text Search. |
|
16. 06. 2012. | #5 |
Pukovnik u penziji
Grand Master
|
Provjeri i koliki je ibdata fajl i pokušaj sa opcijom innodb_file_per_table tako da svaka tabela bude zaseban fajl.
Imao sam slučajeve da baza uspori do iznemoglosti samo zato što je ovaj fajl reda 50GB |
16. 06. 2012. | #6 |
Ivan Dilber
Sir Write-a-Lot
|
Sto se brzine ovog upita tice, problem je u ovom ORDER BY, trebalo bi pokusati da se napravi tako da baza koristi index za sortiranje (prema explainu ne koristi ga trenutno).
Probaj da napravis UNIQUE KEY (`articleID`, `wordID`) ili obrnuto sa (`wordID`, `articleID`), pa vidi da li ce onda explain da ti da "using index". Takodje prebaci brojanje da bude COUNT(*), u mysql manualu preporucuju da se ne navodi polje da bi mogle da se odrade sve optimizacije... Ali u svakom slucaju neces moci da dostignes performanse koje ima full-text search jer on koristi specijalan index optimizovan za tu vrstu pretrage... Imas par mogucnosti: - da vratis myisam, ali ubacis replikaciju na kojoj ces raditi search, da izbegnes lock tabele (po meni to ti je previse komplikacija) - da predjes na Lucene, Solr ili tako neki specijalizovani search engine - da koristis memcached da iskesiras podatke iz baze u jedan lookup hash za sve reci i artikle - da umesto ove 2 tabele koje koristis napravis jednu myIsam tabelu sa spiskom svih reci i articleID-jem za svaku i da onda koristis full-text search na njoj
__________________
Leadership is the art of getting people to want to do what you know must be done. |
"Hvala" ivanhoe za poruku: |
16. 06. 2012. | #7 |
Super Moderator
Knowledge base
Datum učlanjenja: 02.10.2006
Lokacija: Niš
Poruke: 1.618
Hvala: 263
275 "Hvala" u 104 poruka
|
baza 99% vremena koristi u statusu 'Sending data' [to sam zaboravio da kazem] - sto mi govori da ORDER nije problem.
sta vise, mislim da se ORDER tek na kraju izvrsi, posle HAVING, a tada mu ostane svega par rezultata koje treba da poredja. ibdata fajl je 31 GB - ali fora je sto su meni [na celom serveru] samo te dve tabele u InnoDB formatu, pri cemu je ova druga 80 puta veca od prve - pa cak i da ih razdvojim - dobio bi jedan fajl od 1GB i drugi opet od 30GB - nista ne bih postigao slucaj 'zakljucavanja tabele' se javlja sto se cesto [tipa na svakih 10 sekundi] menja sadrzaj nekog artikla - pa samim tim treba i izbaciti iz ove druge tabele reci koje su bile u tom artiklu - i dodati nove. tada [pri brisanju] zbog myisam implementacije, tabela sama od sebe biva zakljucana, pa SELECT [na koji cekaju posetioci] ne bi smeo da ceka puno [mada mi se cini da nisu ni cekali puno]. to brisanje je background proces - i moze da se 'odlozi' - samo nisam siguran da moze da se napravi tako da query DELETE stane u sred izvrsavanja da bi SELECT prosao istog trena - a to meni sustinski treba zapravo [ako bi se vratio na myisam] sve vise razmisljam o myisam full text search... to mi se cini kao mozda zaokruzeno resenje, bez mnogo glavobolja... Poslednja izmena od Peca : 16. 06. 2012. u 18:15. |
16. 06. 2012. | #8 |
Super Moderator
Knowledge base
Datum učlanjenja: 02.10.2006
Lokacija: Niš
Poruke: 1.618
Hvala: 263
275 "Hvala" u 104 poruka
|
probacu ovo, deluje logicno, posto upit kombinuje ta dva polja preko GROUP BY...
Poslednja izmena od Peca : 16. 06. 2012. u 21:10. |
16. 06. 2012. | #9 |
Super Moderator
Knowledge base
Datum učlanjenja: 02.10.2006
Lokacija: Niš
Poruke: 1.618
Hvala: 263
275 "Hvala" u 104 poruka
|
postoji li neki nacin [query] da eliminisem duplikate za ta dva polja, posto je ipak uleteo dupli unos za jedan artikal
EDIT: nadjoh: ALTER IGNORE TABLE... Poslednja izmena od Peca : 16. 06. 2012. u 21:41. |
24. 06. 2012. | #10 |
Super Moderator
Knowledge base
Datum učlanjenja: 02.10.2006
Lokacija: Niš
Poruke: 1.618
Hvala: 263
275 "Hvala" u 104 poruka
|
sta bi trebao da pokaze EXPLAIN da bih bio siguran da on sada koristi ovaj novi UNIQUE KEY?
i dalje pod Extra pise Using where... :/ doduse, naveo je ovaj novi kljuc pod possible_keys... Poslednja izmena od Peca : 24. 06. 2012. u 15:41. |
|
|