Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [mysql] wybieranie losowego wpisu
Force
post
Post #1





Grupa: Zarejestrowani
Postów: 55
Pomógł: 6
Dołączył: 17.05.2007

Ostrzeżenie: (0%)
-----


Witam

Na początku zaznaczam że szukałem na forum i nic nie znalazłem więc jeżeli było to proszę o linka

Pobieram z bazy danych losowe wpisy takim pytaniem:
"SELECT * FROM obrazki ORDER BY RAND() LIMIT 10"
Niestety przy 400 wpisach pytanie wykonuje się ok 0.2s
Czy jest jakiś szybszy sposób na to?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 5)
Cezar708
post
Post #2





Grupa: Zarejestrowani
Postów: 1 116
Pomógł: 119
Dołączył: 10.05.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Cytat
RAND() is not meant to be a perfect random generator, but instead is a fast way to generate ad hoc random numbers which is portable between platforms for the same MySQL version.
(źródło)


więc używanie rand() samo w sobie nie jest efektywne. Nie wiem jaki rodzaj danych masz w tej tabeli ale myślę, że lepszym rozwiązaniem byłoby gdzieś zkacheowanie wszystkich ID do tablicy w pliku PHP i potem z niej na poziomie PHP losować id i dać zapytanie:

  1. SELECT *
  2. FROM obrazki WHERE id_obrazka IN ( 12, 142, 195, 543, 834, 2345 ,.... i tak dalej...


Funkcje losującą identyfikatory ze skeszowanej tablicy PHP można łatwo napisać za pomocą funkcji int rand ( [int $min, int $max] )
Go to the top of the page
+Quote Post
Force
post
Post #3





Grupa: Zarejestrowani
Postów: 55
Pomógł: 6
Dołączył: 17.05.2007

Ostrzeżenie: (0%)
-----


Mam mniej więcej taką tabelę
  1. CREATE TABLE `obrazki` (
  2. `pid` int( 11 ) NOT NULL AUTO_INCREMENT ,
  3. `aid` int( 11 ) NOT NULL DEFAULT '0',
  4. `filepath` varchar( 255 ) NOT NULL DEFAULT '',
  5. `filename` varchar( 255 ) NOT NULL DEFAULT '',
  6. `filesize` int( 11 ) NOT NULL DEFAULT '0',
  7. `title` varchar( 255 ) NOT NULL DEFAULT '',
  8. PRIMARY KEY ( `pid` ) ,
  9. KEY `owner_id` ( `owner_id` ) ,
  10. ) ENGINE = MyISAM DEFAULT CHARSET = latin2

Ma ktoś jakiś pomysł jak to zrobić inaczej?
Cytat
Nie wiem jaki rodzaj danych masz w tej tabeli ale myślę, że lepszym rozwiązaniem byłoby gdzieś zkacheowanie wszystkich ID

Czyli mam wybrać wszystkie identyfikatory obrazków?
  1. SELECT pid FORM obrazki


I jeszcze jedno pytanie:
Czy funkcja array_rand zapewnia to, że wybrane elementy tablicy nie będą się powtarzać?
Go to the top of the page
+Quote Post
nevt
post
Post #4





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

Ostrzeżenie: (0%)
-----


ja bym to spróbował zrobić na 2 zapytaniach, pierwsze
  1. SELECT COUNT(*) FROM `obrazki`;

zakładając, że w zmiennej $count mamy wynik pierwszego zapytania, budujemy w PHP drugie:
  1. <?php
  2. $random = rand(0, $count -);
  3. $sql = "SELECT * FROM `obrazki` LIMIT $random, 1;";
  4. ?>

dla dużych ilości danych nie widzę wydajniejszej metody... nie wymaga przesyłania dużych ilości danych ani sortowania tablic, nie wymaga zakładania specjalnych indeksów w tabeli z której losujemy... życie byłoby jeszcze prostsze, gdyby klauzula LIMIT w MySQL dopuszczała jako parametr coś innego niż stałą liczbową, wtedy można by to zrobić w jednym zapytaniu.

pozdrawiam.

Ten post edytował nevt 16.01.2008, 21:37:54


--------------------

-
Oh no, my young coder. You will find that it is you who are mistaken, about a great many things... -
Go to the top of the page
+Quote Post
Force
post
Post #5





Grupa: Zarejestrowani
Postów: 55
Pomógł: 6
Dołączył: 17.05.2007

Ostrzeżenie: (0%)
-----


nevt: Tylko, że ja wyciągam z bazy ponad 10 wpisów a to pytanie: "SELECT * FROM `obrazki` LIMIT $random, 1;" przy 4000 wpisach wykonywało się prawie tyle samo co wyciągnięcie 10 wpisów z pomocą RAND()
Go to the top of the page
+Quote Post
Cezar708
post
Post #6





Grupa: Zarejestrowani
Postów: 1 116
Pomógł: 119
Dołączył: 10.05.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Cytat(Force @ 16.01.2008, 21:26:37 ) *
Czyli mam wybrać wszystkie identyfikatory obrazków?
  1. SELECT pid FROM obrazki

tak i zapisz je w jakiejś tablicy. Jeśli dane w tabeli się często nie zmieniają warto by było taką tablicę gdzieś w pliku PHP po prostu zapisać

Cytat(Force @ 16.01.2008, 21:26:37 ) *
I jeszcze jedno pytanie:
Czy funkcja array_rand zapewnia to, że wybrane elementy tablicy nie będą się powtarzać?


W zasadzie to nie zapewnia, ale zawsze możesz sprawdzać, czy dana wartość jest w tablicy (in_array), jest to trochę dłuższe...

Ewentualnie jeśli liczba tych wylosowanych obrazków nie jest krytycznie ważna to możesz posłużyć się statystyką. Czyli w zależności od liczby rekordów losujesz na przykład 12 i robisz zapytanie:

  1. SELECT DISTINCT * -- DISTINCT, żeby rekordy się nie powtarzały
  2. FROM obrazki WHERE pid IN ( (i tu te przykładowe 12 wartości )
  3. LIMIT 10 -- żeby w razie jak wszystkie wartości są różne to aby tylko 10 pierwszych wyników zabrać
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 21.08.2025 - 06:22