![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 651 Pomógł: 116 Dołączył: 3.06.2012 Skąd: Lędziny Ostrzeżenie: (0%) ![]() ![]() |
Zastanawiam się jaki jest najoptymalniejszy sposób na wybranie 5 losowych rekordów z bazy danych? Do tej pory raczej bezmyślnie korzystałem z rand() w zapytaniu, ale ta opcja ma bardzo negatywne opinie w sieci, dlatego też zastanawiam się w jaki sposób to zrobić inaczej, a przy tym najbardziej optymalnie jak tylko się da?
|
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 72 Pomógł: 16 Dołączył: 21.06.2013 Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 651 Pomógł: 116 Dołączył: 3.06.2012 Skąd: Lędziny Ostrzeżenie: (0%) ![]() ![]() |
Cóż, używam czegoś takiego:
ale coś jest nie tak... Mam w bazie 7 rekordów, pasujących do tego zapytania, a wymagam tylko 5 losowych. To zapytanie w rezultacie raz daje mi 3 wyniki, raz 4, raz 5, a raz jedno... Co jest nie tak ? |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 1 421 Pomógł: 310 Dołączył: 18.04.2012 Ostrzeżenie: (0%) ![]() ![]() |
FLOOR(Max(id)*RND()) zwrca ci jakś konkretną liczbę. I wybierasz id>= od tej liczby. Czasem nie ma ich 5
Jeśli chcesz pseudolosowo wybrać 5 rekordów bez rand, t spróbuj cegoś tkiego: SELECT * FROM `table` WHERE promote = 1 ORDER BY crc32(concat(unix_timestamp(),id)) LIMIT 5 |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 321 Pomógł: 55 Dołączył: 19.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
zaciekawił mnie temat , bo od czasu do czasu też korzystałem z RAND bez jakiegoś szczególnego przemyślenia. Zrobiłem mały test , może ktoś ma chwilę i potwierdzi lub ... ?
test-1 Kod $sql = SELECT * FROM tab WHERE param1 =1 ORDER BY RAND() LIMIT 5 test-2 Kod $sql = SELECT * FROM tab WHERE param1 =1 ORDER BY crc32(concat(unix_timestamp(),id)) LIMIT 5 test-3 Kod $sql1 = 'SELECT MAX(id) as max , MIN(id) as min FROM tab $Rand - tablica pięcoelementowa z rand(min,max), bez duplikatów $sql2 = SELECT * FROM tab WHERE param1 =1 AND id IN ($Rand); Poniżej czas wykonania 100 razy danego testu na tabelach z określoną ilością rekordów Kod +--------------+-------------------------+------------------------+------------------------+
| tab/test | test-1 | test-2 | test-3 | +--------------+-------------------------+------------------------+------------------------+ | 0,1 k | 0.097609996795654 | 0.10826182365417 | 0.21252417564392 | | 1 k | 0.411727905273440 | 0.37512493133545 | 0.11276888847351 | | 10 k | 2.324110031127900 | 1.72308802604680 | 0.13337612152100 | | 100 k | 30.56501388549800 | 8.64563798904420 | 0.16905999183655 | 1 500 k | 495.1988191604600 | 38.3752229213710 | 0.17194390296936 | +--------------+-------------------------+------------------------+------------------------+ |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 72 Pomógł: 16 Dołączył: 21.06.2013 Ostrzeżenie: (0%) ![]() ![]() |
Problem pojawi się dopiero gdy będziesz miał "przerwy" w ID i wylosujesz elementy nieistniejące wówczas zapytanie nie zwróci pięciu rekordów.
|
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 2 355 Pomógł: 533 Dołączył: 15.01.2010 Skąd: Bydgoszcz Ostrzeżenie: (0%) ![]() ![]() |
Kiedyś poruszałem ten temat w innym wątku, twierdząc, że aktualnie ORDER BY RAND() jest równie szybkie.
ctom: Jaką wersję MySQL wykorzystałeś do testów? U mnie zapytanie:
Wszystkich rekordów: 350k Czas średni na 20 powtórzeń: 0,140 sec. |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 321 Pomógł: 55 Dołączył: 19.04.2009 Ostrzeżenie: (0%) ![]() ![]() |
@c1chy - fakt , to całkowicie wyklucza używanie rozwiązania z test-3
ctom: Jaką wersję MySQL wykorzystałeś do testów? mysql Ver 14.14 Distrib 5.5.31, for debian-linux-gnu (x86_64) using readline 6.2 - ale to nie jest na żadnym produkcyjnym serwerze, tylko na desktopie z domyślną konfiguracją Wszystkich rekordów: 350k Czas średni na 20 powtórzeń: 0,140 sec. @Damonsson- to jest średni czas z 20 powtórzeń czy SUMA czasów 20 wykonań zapytania? Ten post edytował ctom 26.11.2013, 19:20:44 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 14.09.2025 - 21:06 |