DevProTalk

DevProTalk (http://www.devprotalk.com/index.php)
-   SQL baze podataka - Sponzor: Baze-Podataka.net (http://www.devprotalk.com/forumdisplay.php?f=10)
-   -   Brisanje većeg broja slogova iz MySQL baze (http://www.devprotalk.com/showthread.php?t=2775)

Dragi Tata 20. 04. 2007. 14:40

Brisanje većeg broja slogova iz MySQL baze
 
Recimo da imam tabelu i da korisnik može da vrši neke prilično složene (i skupe) pretrage nad tom tabelom, a ako mu padne napamet i da izbriše sve rezultate neke od tih pretraga.

U prvom prototipu, jednostavno pamtim id-ove svih slogova koji su pronađeni pretragom i onda ako korisnik tako odluči u jednoj petlji brišem slogove po id-u. Ovo naravno radi, ali gledam da to uradim malo efikasnije/elegantnije. Koliko kapiram, MySQL podržava IN sintaksu, pa bih mogao nešto kao:

DELETE FROM tabela WHERE id IN (1, 5, 8...)

Koliko vidim, jedino ograničenje za IN je max_allowed_packet, ali ne znam kako bi ovo uticalo na performanse.

Da li bi "prepared statement" možda bilo bolje rešenje?

Mišljenja, ideje?

Hvala unapred.

Petar Marić 20. 04. 2007. 15:06

Koliko znam ne postoji brži način, osim ako ne brišeš celu tabelu (tada je AFAIK TRUNCATE brži).

Mislim da te max_allowed_packet promenljiva (podrazumevano je 16MB) ne treba da brine, osim ako nemaš nekoliko miliona id-ova u IN klauzuli.

ivanhoe 20. 04. 2007. 15:12

koliko ja znam IN koristi indexe... koristim ga vrlo cesto upravo za te "delete all checked" operacije i nisam nikad imao nekih problema, niti problema sa perfomansama...cak mislim da je to brze od petlje koja brise jedan po jedan rekord cak i kad je sql izraz prepared (sto do nedavno nije moglo iz php-a, pa sam zato i navikao na IN), jer se ipak sve odvija interno u mysql-u...

u svakom slucaju sa indexiranom tabelom IN radi vrlo lepo..

jablan 20. 04. 2007. 15:12

A dodatna tabela (idpretrage, id) ti ne odgovara?

Dragi Tata 20. 04. 2007. 15:59

@Petar, ivanhoe:

Hvala, to mi savetuje i DBA.

Citat:

Originalno napisao jablan
A dodatna tabela (idpretrage, id) ti ne odgovara?

Misliš da rezultate pretrage čuvam u posebnoj tabeli, pa ako korisnik reši da briše da udarim Delete po subqueriju iz te tabele?

Interesantan pristup, samo je problem što obično ima mnogo pretraga a malo brisanja. Dokle da držim te pretrage u bazi i kad da ih brišem? Mislim da temp tabela ne dolazi u obzir jer korisnik vrši pretragu tokom jedne (http) konekcije a briše u drugoj.

jablan 20. 04. 2007. 16:06

Citat:

Originalno napisao Dragi Tata
Misliš da rezultate pretrage čuvam u posebnoj tabeli, pa ako korisnik reši da briše da udarim Delete po subqueriju iz te tabele?

Da, da. Mislim, ne tvrdim da je to rešenje bolje, samo ga navodim kao jedno od mogućih.

Što se brisanja tiče, sve zavisi od prirode aplikacije, količine podataka, učestalosti brisanja i punjenja itd. Jedno od rešenja je da se koristi timestamp i da se brišu sve pretrage starije od nekog određenog intervala.

Dragi Tata 20. 04. 2007. 16:23

Kao što rekoh u mom slučaju ima mnogo više pretraga nego brisanja, pa se bojim da tako nešto ne bi bilo uputno, ali generalno gledano nije loša ideja.

Thx.

dinke 21. 04. 2007. 00:17

Mislim da je ovo prvo resenje optimalnije po nacinu upotreba indexa od ovog sa subquerijem. Koliko se secam literature (nisam preterano koristio subquerije u praksi), do MySQL-a 5.1 optimizacija je bolje funkcionisala kada se ne koriste podupiti.

Ukratko:

Kôd:

delete from foo where id in (1,2,3)
je optimalnije nego

Kôd:

delete from foo where id in (select id from temp_table)
.

Koga ne mrzi moze i da proba sa malo vecim brojem recorda i odgovarajucim explainom :)

degojs 21. 04. 2007. 02:57

^Jeste, ali šalješ mnogo više podatka preko "žice" do baze ako je IN lista duga.. Petlja je najlošije rešenje, jer za svaki ID moraš ponovo da se konektuješ na bazu - connection pooling u takvom slučaju je verovatno obavezan, ako su performanse bitne.

Jedno od rešenja jeste da koristiš upit:

DELETE FROM t1 WHERE ID IN ( .. originalni upit [izmenjen da selektuje samo ID].. ).

Čime si izbegao da šalješ gomilu ID-ova u IN klauzi, ne treba ni pomoćna tabela, itd. Ovako može jer nema potrebe da navodiš "novu" listu ID-ova u IN klauzi, pošto, čini mi se, reče da brišeš sve zapise koji su prethodno bili vraćeni nekim upitom - samo ponovi taj isti, malo izmenjen, SELECT u podupitu za IN. Ako još možeš da taj upit izraziš sa prepared statement-om, ne izgleda mi loše rešenje, posebno što bi baza kod brisanja već mogla da ima keširane potrebne ID-ove nakon prvog upita.

Treba probati :)

ivanhoe 21. 04. 2007. 12:23

mozda neka pametnija baza, mysql ce taj originalni upit da ponovi jer query nije identican (mora do poslednjeg karaktera da bude isti da bi mysql koristio cache)


Vreme je GMT +2. Trenutno vreme je 14:35.

Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.

Mišljenja, saveti, izjave, ponude ili druge informacije ili sadržaji nastali na Sajtu su vlasništvo onoga ko ih je kreirao, a ne DevProTalk.com, tako da ne morate da se oslanjate na njih.
Autori poruka su jedini odgovorni za ovakve sadržaje. DevProTalk.com ne garantuje tačnost, kompletnost ili upotrebnu vrednost informacija, stavova, saveta ili datih izjava. Ne postoje uslovi pod kojima bi mi bili odgovorni za štetu ili gubitak koji je posledica bilo čijeg oslanjanja na nepouzdane informacije, ili bilo kakve informacije nastale kroz komunikaciju između registrovanih članova.
Web sajt može sadržavati linkove na druge web sajtove na Internetu ili neke druge sadržaje. Ne kontrolišemo niti podržavamo te druge web sajtove, niti smo pregledali bilo kakve sadržaje na takvim sajtovima. Mi nećemo biti odgovorni za legalnost, tačnost ili prikladnost bilo kog sadržaja, oglasa, proizvoda, usluga ili informacije lociranim na ili distribuiranih kroz druge web sajtove, niti za bilo kakvu štetu nastalu kao posledica takvih informacija. DevProTalk.com drži i čuva druga prava vlasništva na web sajtu. Web sajt sadrže materijale zaštićene copyright-om, zaštitne znakove i druge informacije o pravu vlasništva ili softver. Članovi mogu poslatu informacije zaštićene pravima vlasništva njihovih nosilaca i ona ostaju zaštićena bez obzira da li su oni koji prenose te informacije to naveli ili ne. Osim informacija koje su u javnom vlasništvu ili za koje dobijete dozvolu, nemate pravo da kopirate, modifikujete ili na bilo koji način menjate, objavljujete, prenosite, distribuirate, izvršavate, prikazujete ili prodajte bilo koju informaciju zaštićenu pravima vlasništva. Slanjem informacija ili sadržaja na bilo koji deo DevProTalk.com, Vi automatski dozvoljavate i predstavljate garanciju da imate pravo da dozvolite DevProTalk.com ili članovima DevProTalk.com bespovratnu, kontinualnu, neograničenu, globalnu dozvolu da koriste, kopiraju, izvršavaju, prikazuju i distribuiraju takve informacije i sadržaje i da iz takvih sadžaja koriste bilo koji deo u bilo koje svrhe, kao i pravo i dozvolu da koriste gore navedene sadržaje. Svi zaštitni znakovi (trademarks), logotipi, oznake usluga, firme ili imena proizvoda koji se pominju na ovom web sajtu su vlasništvo kojim raspolažu njihovi vlasnici.