![]() |
![]() |
![]() ![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 12 Pomógł: 0 Dołączył: 6.04.2008 Ostrzeżenie: (0%) ![]() ![]() |
Witam
To mój pierwszy post tutaj, ale zdążyłem zauważyć jak przydatne jest to forum - niejednokrotnie mi pomagało. Ale do rzeczy. 1. Pytanie nr 1: Chcę pobrać losowy rekord z bazy... jak to zrobić? Robię tak: "SELECT * FROM baza ORDER BY rand() LIMIT 1"; Ale podobno używanie rand() nie jest wydajne. Może wydajniej byłoby tak: $pozycja = rand(0,$ilosc_rekordow); // tutaj wcześniej trzeba by dać zapytanie zliczające rekordy "SELECT * FROM baza LIMIT $pozycja,1"; Która opcja lepsza? 2. Pytanie nr 2: jeśli powiecie, żebym sam sprawdził co będzie wydajniejsze, to jak to zrobić? $przed = microtime(); $query = "SELECT * FROM baza ORDER BY rand() LIMIT 1"; $result = mysql_query($query); $po = microtime(); $czas = $po - $przed; W ten sposób będzie dobrze? Dzięki za sugestie. Pozdrawiam Ten post edytował anskellig 6.04.2008, 21:52:01 |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Przyjaciele php.pl Postów: 7 494 Pomógł: 302 Dołączył: 31.03.2004 Ostrzeżenie: (0%) ![]() ![]() |
Metoda 1. odpada, jest jak już wspomniałeś bardzo wolna. Metoda 2. jest całkiem niezłym wyjściem ale najszybsza jest ...
... a co się będę powielał (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Selecting random record from MySQL database table |
|
|
![]()
Post
#3
|
|
Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
Fajne, fajne, ale mozna by sie czepic rozkladu prawdopodobienstwa (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Czesciej beda wybierane rekordy ktore maja przed soba dziure - brakujacych IDkow (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
|
|
|
![]()
Post
#4
|
|
Grupa: Przyjaciele php.pl Postów: 2 923 Pomógł: 9 Dołączył: 25.10.2004 Skąd: Rzeszów - studia / Warszawa - praca Ostrzeżenie: (0%) ![]() ![]() |
@dr_bonzo Doczytaj dokladnie tu nie chodzi o ID. @mike Ciekawe przyklady podales, chociaz ten COUNT dla bardzo duzej ilosci moze roznie dzialac (wolno)
|
|
|
![]()
Post
#5
|
|
Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
SongoQ: no rzeczywiscie, w metodzie 3. wszystko jest ok, ale pozostale maja nadal nierowny rozklad (pomijajac ofkorz 1.)
|
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 12 Pomógł: 0 Dołączył: 6.04.2008 Ostrzeżenie: (0%) ![]() ![]() |
Dzięki za odpowiedzi.
A czy ta 3 metoda (ta najszybsza) nie jest praktycznie taka sama jak moja druga? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Ja też używam w niej LIMIT $offset, 1 (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Tylko że mój $offset jest wyliczany przez rand() w PHP. Możliwe więc, że wychodzi podobnie wydajnie (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) W sumie ja jeszcze dokładam jedno zapytanie zliczające rekordy. Może w ogóle niepotrzebnie się tym martwię, bo moja tabela nie będzie raczej nigdy większa niż kilka tysięcy rekordów. A jeszcze co do tej 3 metody... $offset_result = mysql_query( " SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `table` "); Co robi to FLOOR(RAND()*COUNT(*)) ? Dlaczego rand()*count(*) ? Ten post edytował anskellig 7.04.2008, 19:00:57 |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 74 Pomógł: 4 Dołączył: 7.03.2008 Ostrzeżenie: (0%) ![]() ![]() |
nie ma co strzelac do muchy z armaty (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
po prostu w jezyku ktorego uzywasz do obslugi mysql wygeneruj losowa liczbe z zakresu twoich id np min = 1, max = 9876 dla php uzyj rand() i wynik wstaw w zapytanie SQL wtedy mysql otrzyma dokladne zapytanie a funkcja rand() w php jest szybka!! jak nie znasz min i max dla twojego ID w tabeli, cachuje je, cachowanie to podstawowa metoda w nowoczesnym programowaniu, odczytuj je np przy kazdej akcji usuwania /dodawania zawartosci tabeli i zapisuj do pliku php w postaci <? $min = 1; $max= 9876; ?> i include('./cachowany_plik.php'); dziala blyskawicznie! oczywiscie metode cachowania dobierz do rodzaju twojegfo serwisu najbardziej optymalnie |
|
|
![]()
Post
#8
|
|
Grupa: Przyjaciele php.pl Postów: 5 724 Pomógł: 259 Dołączył: 13.04.2004 Skąd: N/A Ostrzeżenie: (0%) ![]() ![]() |
Tja - keszowanie takiej pierdoly. Juz duzo latwiej przekleic gotowa SQLke i dostosowac do swoich nazw kolumn niz implementowac takie cache.
w sensie ze niepotrzebmie komplikuje aplikacje, i to jest raczej ta armata (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Ten post edytował dr_bonzo 8.04.2008, 05:25:26 |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 12 Pomógł: 0 Dołączył: 6.04.2008 Ostrzeżenie: (0%) ![]() ![]() |
To chyba zostanę przy tej metodzie:
$pozycja = rand(0,$ilosc_rekordow); // tutaj wcześniej trzeba by dać zapytanie zliczające rekordy "SELECT * FROM baza LIMIT $pozycja,1"; Zamiast cachowania więc, będzie zapytanie zliczające rekordy. Dla tabeli o kilku tys. rekordów chyba nie będzie to obciążeniem. Cache'owanie wydaje mi się jednak tą armatą jak pisze poprzednik (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) |
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 74 Pomógł: 4 Dołączył: 7.03.2008 Ostrzeżenie: (0%) ![]() ![]() |
ta ostatnia metoda niczym nie rozni sie od mojej, i tak musisz znac min i max id tabeli, a co jak wygenerujesz liczbe losowa spoza zakresu?
cachowanie brzmi skomplikowanie i powaznie ale to powsechnie uzywana praktyka |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 1 033 Pomógł: 125 Dołączył: 17.09.2005 Skąd: Żywiec Ostrzeżenie: (0%) ![]() ![]() |
Cytat a co jak wygenerujesz liczbę losowa spoza zakresu? No właśnie to twój sposób się na tym wykłada. Co jeśli w bazie będę miał takie dane: Kod +------+ | ID | (...) +------+ | 1 | | 2 | | 5 | | 7 | | 8 | a rand" title="Zobacz w manualu PHP" target="_manual zwróci mi: 3? |
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 12 Pomógł: 0 Dołączył: 6.04.2008 Ostrzeżenie: (0%) ![]() ![]() |
ta ostatnia metoda niczym nie rozni sie od mojej, i tak musisz znac min i max id tabeli, a co jak wygenerujesz liczbe losowa spoza zakresu? Jeśli zrobię tak: $pozycja = rand(0,$ilosc_rekordow); "SELECT * FROM baza LIMIT $pozycja,1"; To rand() nie wylosuje liczby spoza zakresu (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Wszystko chyba OK. Tylko dodatkowe zapytanie zliczające ilość rekordów trzeba dać. |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 74 Pomógł: 4 Dołączył: 7.03.2008 Ostrzeżenie: (0%) ![]() ![]() |
racja, nie pomyslalem o braku id z zadanego zakresu, twoja metoda zdecydowanie lepsza
|
|
|
![]()
Post
#14
|
|
Grupa: Zarejestrowani Postów: 793 Pomógł: 32 Dołączył: 23.11.2006 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
SongoQ: no rzeczywiscie, w metodzie 3. wszystko jest ok, ale pozostale maja nadal nierowny rozklad (pomijajac ofkorz 1.) Wiesz jak chcesz losowo więcej niż jeden, to wybierasz losowo pulę i z niej losowo tyle ile chcesz, wielkość puli też opiera się na zliczaniu krotek i offset więc nie ma różnicy jaki jest rozkład ID w tabeli. Co prawda rozrzut nie będzie duży takich wyborów, ale jak na razie nie widziałem lepszego. (zawsze można dodać dodatkową indeksowaną kolumnę z random i po niej sortować lol wtedy nowe krotki mogą wpadać do starych pul) |
|
|
![]() ![]() |
![]() |
Aktualny czas: 22.08.2025 - 12:44 |