DevProTalk

Forumi IT profesionalaca
web development, web design, e-business, SEO


Idite nazad   DevProTalk > Web development i web aplikacije > SQL baze podataka - Sponzor: Baze-Podataka.net
Želite da se reklamirate ekskluzivno na ovoj poziciji? Javite se

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

Odgovori
 
Alati teme Način prikaza
Staro 08. 04. 2008.   #1
kodi
133t
Master
 
Avatar kodi
 
Datum učlanjenja: 08.01.2006
Lokacija: Beograd
Poruke: 714
Hvala: 16
37 "Hvala" u 28 poruka
kodi is on a distinguished road
Pošaljite ICQ poruku za kodi
Default random select na velikoj tabeli

problem:
imam tabelu (~2M unosa), primarni kljuch je polje id, medjutim ono nije uniformno rasporedjeno, tj postoje veliki blokovi obrisanih unosa, naprimer id moze da ide:
1
2
3
434
454
455
456
900
901
.
.
.
i tako, e sad meni treba query koji ce na najbrzi nacin da mi vrati recimo 2000 random row-ova iz tablele (tih 2000 moraju biti unikatni)

any idea? (mySQL)

P.S.
znam za
ORDER BY RAND()
LIMIT XYZ
ali je to jako sporo, i ima tendenciju da ubije cpu
__________________

Poslednja izmena od kodi : 08. 04. 2008. u 15:14.
kodi je offline   Odgovorite uz citat
Staro 08. 04. 2008.   #2
ivanhoe
Ivan Dilber
Sir Write-a-Lot
 
Avatar ivanhoe
 
Datum učlanjenja: 18.10.2005
Lokacija: Bgd
Poruke: 5.320
Hvala: 104
2.344 "Hvala" u 583 poruka
ivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svima
Pošaljite poruku preko Skype™ za ivanhoe
Default

mozes da smanjis broj recorda koji se sortiraju tako sto ces da stavis:
"WHERE id BETWEEN ". $rand ." AND ". ($rand+10000) ."
ORDER BY RAND()
LIMIT XYZ"

ako 10000 nije dovoljno stavis vecu granicu
__________________
Leadership is the art of getting people to want to do what you know must be done.
ivanhoe je offline   Odgovorite uz citat
Staro 08. 04. 2008.   #3
kodi
133t
Master
 
Avatar kodi
 
Datum učlanjenja: 08.01.2006
Lokacija: Beograd
Poruke: 714
Hvala: 16
37 "Hvala" u 28 poruka
kodi is on a distinguished road
Pošaljite ICQ poruku za kodi
Default

hmm...

to bi definitivno smanjilo vreme, i olaksalo stvari, ali bi onda favorizovalo unose iz tih 10k, sto na 2M unosa nije naivno..
a ako povecam na recimo 100k opet ce trajati mnogo taj query

evo sad googlam, i izgleda da uopste nema lakog resenja za ovaj problem..

jel ima neko neku ideju, ili sam osudjen na dodatno polje sa sekvencom koja ce se updejtovati na svaki insert i delete
__________________
kodi je offline   Odgovorite uz citat
Staro 08. 04. 2008.   #4
zira
Vladan Zirojević
Grand Master
 
Datum učlanjenja: 09.06.2006
Lokacija: Beograd/Trebinje
Poruke: 903
Hvala: 106
183 "Hvala" u 82 poruka
zira ima spektakularnu auruzira ima spektakularnu auruzira ima spektakularnu auru
Pošaljite ICQ poruku za zira Pošaljite poruku preko Skype™ za zira
Default

http://akinas.com/pages/en/blog/mysql_random_row/
Valjda Solution 3 na toj strani pokriva i tvoj slucaj...
__________________
Donesi.com SrediMe

Poslednja izmena od zira : 08. 04. 2008. u 15:58.
zira je offline   Odgovorite uz citat
Staro 08. 04. 2008.   #5
ivanhoe
Ivan Dilber
Sir Write-a-Lot
 
Avatar ivanhoe
 
Datum učlanjenja: 18.10.2005
Lokacija: Bgd
Poruke: 5.320
Hvala: 104
2.344 "Hvala" u 583 poruka
ivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svima
Pošaljite poruku preko Skype™ za ivanhoe
Default

@zira: ovaj primer dohvat samo jedan rekord

@kodi: mozes da umesto jednog opsega od 10000 rekorda dohvatis par manjih (5-6 recimo, ili koliko mislis da ti treba), pa da ih unijom spojis, pa onda na celom rezultatu uradis ORDER BY rand()

u sustini, ovde ti je pitanje jel ti treba stroga uniformna raspodela verovatnoce, ili ti treba brzina, treba naci neki najbolji odnos..
__________________
Leadership is the art of getting people to want to do what you know must be done.
ivanhoe je offline   Odgovorite uz citat
Staro 08. 04. 2008.   #6
kodi
133t
Master
 
Avatar kodi
 
Datum učlanjenja: 08.01.2006
Lokacija: Beograd
Poruke: 714
Hvala: 16
37 "Hvala" u 28 poruka
kodi is on a distinguished road
Pošaljite ICQ poruku za kodi
Default

Citat:
u sustini, ovde ti je pitanje jel ti treba stroga uniformna raspodela verovatnoce, ili ti treba brzina, treba naci neki najbolji odnos..
:/

trabaju mi oba

odustao sam od uniformne raspodele, i posto ti blokovi obrisanih podataka nisu toliko veliki uradio sam varijantu da prvo u phpu generishem niz sa offsetima a onda fetchujem sa where id >=$offset, radi prilichno brzo....


Off Topic:
btw, radi se o gomili keyworda, cije rezultate sa googla treba da updatujem i da sve bude mladje od 10 dana, u medjuvremenu je dataset bash narastao, tako da smo preshli na model gde se na svakihsat vremena updejtuje deo sadrzaja, a onda na svakih 10 dana pokrene skripta koja pokupi sve sto je po timestamp-u starije od 10dana, obichno ostane manje od procenat onoga sto se ovakvom metodom promashi, a generalno podaci budu mnogo sveziji, samo treba nashtelovati koliku porciju da uzima pri svakom prolazu i koliko chesto to da ide

eto mozda nekome bude korisno...
__________________

Poslednja izmena od kodi : 08. 04. 2008. u 20:51.
kodi je offline   Odgovorite uz citat
Staro 08. 04. 2008.   #7
conica
Pilece krilce(reš)
Master
 
Avatar conica
 
Datum učlanjenja: 12.01.2006
Lokacija: Little boy's playground
Poruke: 604
Hvala: 47
61 "Hvala" u 27 poruka
conica će postati "faca" uskoro
Pošaljite ICQ poruku za conica Pošaljite poruku preko MSN za conica Pošaljite poruku preko Skype™ za conica
Default

evo dodjosmo do ovoga
PHP kôd:
SELECT FLOOR(+ (RAND() * (SELECT COUNT(*) from table_name))) from table_name limit 4
primer je testiran na tabeli sa oko 1.200.000 recorda sa limitom 4
__________________
HomeOfWeb | BLOG: (hrk)pljuc.com
conica je offline   Odgovorite uz citat
Staro 08. 04. 2008.   #8
kodi
133t
Master
 
Avatar kodi
 
Datum učlanjenja: 08.01.2006
Lokacija: Beograd
Poruke: 714
Hvala: 16
37 "Hvala" u 28 poruka
kodi is on a distinguished road
Pošaljite ICQ poruku za kodi
Default

nisam siguran da razumem najbolje ovo, ovo mi vrati samo xyz id-jeva.. opet bih morao da radim fetch za svaki od njih, a i cini mi se da je moguce da mi vrati id koji je recimo izbrisan (?) ili greshim ?
__________________
kodi je offline   Odgovorite uz citat
Staro 08. 04. 2008.   #9
ivanhoe
Ivan Dilber
Sir Write-a-Lot
 
Avatar ivanhoe
 
Datum učlanjenja: 18.10.2005
Lokacija: Bgd
Poruke: 5.320
Hvala: 104
2.344 "Hvala" u 583 poruka
ivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svimaivanhoe je ime poznato svima
Pošaljite poruku preko Skype™ za ivanhoe
Default

A mozda moze da se naprosto izgenerise jedno 4000 random brojeva (lepa okrugla cifra), i onda uradis:

SELECT * FROM tabela
WHERE id IN ($gomila_rnd_brojeva)
ORDER BY RAND()
LIMIT 2000;

Ako ti se ne vrati dovoljno rezultata uradis naprosto ponovo upit sa korigovanim limitom, i tako sve dok ne skupis dovoljno...
__________________
Leadership is the art of getting people to want to do what you know must be done.
ivanhoe je offline   Odgovorite uz citat
Staro 09. 04. 2008.   #10
Dejan Topalovic
old school
Professional
 
Datum učlanjenja: 15.02.2006
Lokacija: Wien, Austria
Poruke: 304
Hvala: 121
47 "Hvala" u 26 poruka
Dejan Topalovic će postati "faca" uskoro
Pošaljite poruku preko MSN za Dejan Topalovic
Default

Nadam se da ovaj kôd govori sve sam od sebe i da ne moram komentarisati nista
Kôd:
use test;
create table keywords (
  id int unsigned not null auto_increment,
  keyword varchar(32) not null,
  url varchar(255),
  primary key(id)
);
DELIMITER $$
DROP PROCEDURE IF EXISTS test.unesi_podatke $$
CREATE PROCEDURE test.unesi_podatke(IN koliko INT)
BEGIN
DECLARE brojac INT DEFAULT 1;
while brojac <= koliko do
INSERT INTO keywords (id, keyword, url)
VALUES(NULL, CONCAT('keyword_', brojac), CONCAT('http://www.url', brojac, '.com'));
set brojac = brojac + 1;
end while;
END $$
DELIMITER ;

mysql> create table keywords (
    ->   id int unsigned not null auto_increment,
    ->   keyword varchar(32) not null,
    ->   url varchar(255),
    ->   primary key(id)
    -> );
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER $$
mysql> DROP PROCEDURE IF EXISTS test.unesi_podatke $$
Query OK, 0 rows affected (0.03 sec)
mysql> CREATE PROCEDURE test.unesi_podatke(IN koliko INT)
    -> BEGIN
    -> DECLARE brojac INT DEFAULT 1;
    -> while brojac <= koliko do
    -> INSERT INTO keywords (id, keyword, url)
    -> VALUES(NULL, CONCAT('keyword_', brojac), CONCAT('http://www.url', brojac,
 '.com'));
    -> set brojac = brojac + 1;
    -> end while;
    -> END $$
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> call test.unesi_podatke(2000000);
Query OK, 1 row affected (1 min 31.95 sec)
mysql> select count(*) from keywords;
+----------+
| count(*) |
+----------+
|  2000000 |
+----------+
1 row in set (0.00 sec)
mysql> create index indeks_id on keywords(id);
Query OK, 2000000 rows affected (15.28 sec)
Records: 2000000  Duplicates: 0  Warnings: 0
mysql> DELETE FROM keywords WHERE mod(id, 7) = 0;
Query OK, 285714 rows affected (6.06 sec)
mysql>
mysql> select count(*) from keywords;
+----------+
| count(*) |
+----------+
|  1714286 |
+----------+
1 row in set (0.00 sec)
 
mysql> select * from keywords
    -> order by rand()
    -> limit 2000;
2000 rows in set (1 min 43.15 sec)

mysql> SELECT *
    -> FROM keywords k
    -> JOIN (SELECT FLOOR( MAX(ID) * RAND()) AS Rand_ID FROM keywords) AS x
    -> ON k.id >= x.Rand_ID
    -> limit 2000;
2000 rows in set (0.63 sec)
Posto je RAND() prilicno spor, mozes upit iz PHP-a proslijediti i drugacije:
Kôd:
$sql = "SELECT * FROM keywords k JOIN (SELECT FLOOR( MAX(ID) * ".lcg_value().") AS Rand_ID FROM keywords) AS x ON k.id >= x.Rand_ID limit 2000";
Ukoliko takav upit proslijedis MySQL-u, mozes dobiti npr. ovakav rezultat:
Kôd:
mysql> SELECT *
    ->  FROM keywords k
    ->  JOIN (SELECT FLOOR( MAX(ID) * 0.234) AS Rand_ID FROM keywords) AS x
    ->  ON k.id >= x.Rand_ID
    ->  limit 2000;
2000 rows in set (0.02 sec)
Nema na cemu.
__________________
Blog: Baze podataka
------------------------
Oracle OCP DBA
Oracle OCE SQL Expert
Oracle OCP Developer
Certified MySQL DBA

Poslednja izmena od Dejan Topalovic : 09. 04. 2008. u 00:48. Razlog: Dodana napomena za lcg_value()
Dejan Topalovic je offline   Odgovorite uz citat
2 članova zahvaljuje Dejan Topalovic za poruku:
Odgovori


Alati teme
Način prikaza

Pravila pisanja
Možete ne započinjati nove teme
Možete ne slati odgovore
Možete ne slati priloge
Možete ne izmeniti svoje poruke
vB kôd je Uključen
Smajliji su Uključen
[IMG] kod je Uključen
HTML kôd je Isključen
Pogledajte forum

Slične teme
Tema Početna poruka teme Forum Odgovori Poslednja poruka
random + mysql mega023 PHP 9 09. 03. 2010. 17:08
Raspored sirine celija u tabeli misk0 (X)HTML, JavaScript, DHTML, XML, CSS 7 06. 05. 2008. 21:18
random koji favorizuje kodi Programiranje 16 29. 04. 2007. 22:09
java.util.Random security Ivan Programiranje 0 02. 01. 2007. 19:43
Random image - preraditi za flash... headcutter (X)HTML, JavaScript, DHTML, XML, CSS 4 02. 09. 2005. 23:14


Vreme je GMT +2. Trenutno vreme je 13:23.


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.