![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 6 799 Pomógł: 1827 Dołączył: 11.03.2014 Ostrzeżenie: (0%) ![]() ![]() |
Witajcie,
zna ktoś może inny sposób niż zopytmalizowany ORDER BY RAND() poprzez ID>=FLOOR(1+RAND()*MAX(ID)) ? Chodzi o to, że metoda ma mankament przy nieciągłości ID. Przykładowo: ID 126 0 134 0,666666667 136 0,833333333 137 0,916666667 138 1 Jak z tego wynika pierwsze ID wpada w połowę dolnego przedziału. Ostatecznie zastosowałem PHP, ale być może zna ktoś rozwiązanie na poziomie SQL. -------------------- |
|
|
![]()
Post
#2
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Najlepszy bylby limit, ale do tego musisz uzyc jeszcze php
- zliczasz liczbę rekordów - na podstawie liczby rekordów losujesz liczbę z zakresu 1:liczba rekordów. Robisz to w php przy pomocy rand() - mając wylosowaną liczbę ($losowa) pobierasz wylosowany rekord ze swojej tabeli przy uzyciu limit SELECT * FROM `tabela` WHERE limit $losowa,1 -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#3
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Podstawowe pytanie: jakiej mniej-więcej wielkości jest pula rekordów spośród których chcesz losować wiersz? Jeżeli jest ona względnie niewielka zwykłe ORDER BY RAND() jest jak najbardziej poprawnym rozwiązaniem. Jeżeli jednak tych rekordów jest sporo skorzystaj z rozwiązania zasugerowanego przez @nospor.
Ten post edytował Crozin 6.08.2014, 10:28:21 |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 6 799 Pomógł: 1827 Dołączył: 11.03.2014 Ostrzeżenie: (0%) ![]() ![]() |
Crozin, nie jest duża, ale ruch w serwisie jest bardzo duży, stąd zdecydowałem o tym.
Rozwiązanie nospor, ciekawe, choć jeśli i tak mam zaprzęgać PHP, to zastosowałem: -------------------- |
|
|
![]()
Post
#5
|
|
![]() Grupa: Zarejestrowani Postów: 420 Pomógł: 44 Dołączył: 22.10.2008 Ostrzeżenie: (0%) ![]() ![]() |
a co jest w $arr wszystkie rekordy z tabeli?
-------------------- Sztuką jest widzieć to czego nie widać.
|
|
|
![]()
Post
#6
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
@trueblue ale w swoim rozwiązaniu musisz pobrac wszystkie rekordy do php co jest bez sensu
-------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 6 799 Pomógł: 1827 Dołączył: 11.03.2014 Ostrzeżenie: (0%) ![]() ![]() |
@trueblue ale w swoim rozwiązaniu musisz pobrac wszystkie rekordy do php co jest bez sensu Gdy ich jest maksymalnie 50? Uprzedzam ponownie, musiałem zoptymalizować ORDER BY RAND(), takie info dostałem od administratorów serwera. -------------------- |
|
|
![]()
Post
#9
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Pry 50 rekordach order by rand nie powinno mulic i byc wolniejsze od tego co robisz w php.
Ale z ciekawosci można by sprawdzić. ps: tak rozumiem, ze musiales sie tego pozbyc bo ci kazali. Ale to wyglada teraz tak, jakbys jednego "zamulacza" zamienial na drugiego ![]() ps2: jesli bedziesz robil testy to dorzuc tez moją wersję. Kto wie co moze wyjsc przy tak malej liczbie rekordow ![]() @Pyton a niby w czym mialo pomoc Twoje zapytanie? Przeciez tam ciagle jest order by RAND -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#10
|
|
![]() Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
W tym że pobiera tylko jedną kolumnę ID, która jest kluczem
|
|
|
![]()
Post
#11
|
|
![]() Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
@trueblue: Jeżeli masz raptem 50 rekordów spośród których chcesz losować to ORDER BY RAND() pewnie będzie najszybszym rozwiązaniem. Masz w ogóle jakieś konkretne powody by myśleć, że to właśnie to zapytanie odpowiedzialne jest za problemy z wydajnością? Czy tylko ktoś zobaczył ten fragment kodu i od razu uznał, że to musi być powodem wszystkich problemów?
|
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 1 421 Pomógł: 310 Dołączył: 18.04.2012 Ostrzeżenie: (0%) ![]() ![]() |
rownie dobrze mozesz zrobic
ale z obserwacji wynika, ze crc32 jest nieco szybsze Ma to taka zalete, ze jesli zapiszesz sobie gdzies current_timestamp, to mozesz odtworzyc kolejnosc. Tak samo jak w ORDER BY Rand(parametr) |
|
|
![]()
Post
#13
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
@Pyton faktycznie masz racje. Pobranie jednej kolumny dla order by rand jest o niebo szybsze niz wszystkich. Testowalem na 500tys rekordow. Wszystkie losowal w 15 sekund, jedną w pol sekundy
ps: rozwiązanie podane przez mmmmmmm jest bardzo ciekawe i dla 500tys rekordow trwa rowniez ok. pol sekundy i można pobrac od razu wszystkie dane bez joinowania -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#14
|
|
Grupa: Zarejestrowani Postów: 6 799 Pomógł: 1827 Dołączył: 11.03.2014 Ostrzeżenie: (0%) ![]() ![]() |
1. Moja metoda
2. Nospor ze znikomym opóźnieniem, praktycznie ex aequo 3. ID>=FLOOR(1+RAND()*MAX(ID)) ok. 33% wolniejsze 4. Pyton_000 ok. 57% wolniejsze 5. mmmmmm ok. 62% wolniejsze Crozin, nie z kodu, z logów, ale nie mam pojęcia jakich, nie wierzę, że ze slowlog. P.S. Być może na tysiącach rekordów wynik byłby zupełnie inny. Ten post edytował trueblue 6.08.2014, 11:32:07 -------------------- |
|
|
![]()
Post
#15
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
Nom, przy malej liczbie rekordow miejsca 1 i 2 mogly tak sie klasowac. Przy wiekszej bylaby juz znaczaca roznica. No ale jesli faktycznie masz tam tylko 50 rekordow to nie ma co sie szczypac.
-------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#16
|
|
![]() Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
Jeżeli różnica rzędu 0.03 to taka wielka różnica
![]() Olałbym sprawę dla takiej małej ilości rekordów, bo faktycznie wykonywanie dziwactwa zajmie więcej czasu niż samo zapytanie. |
|
|
![]()
Post
#17
|
|
![]() Grupa: Moderatorzy Postów: 36 557 Pomógł: 6315 Dołączył: 27.12.2004 ![]() |
@Pyton przy 50 rekordach nie ma co oczekiwac, ze roznice będą większe.
Zas przy 500 tysiacach, twoj skrypt wykonuje sie pol sekundy, moj 0,001s. Zas przy takiej liczbie rekordow (500 tys) rozwiązanie trueblue nie mialoby w ogole sensu. -------------------- "Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista "Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer |
|
|
![]()
Post
#18
|
|
Grupa: Zarejestrowani Postów: 6 799 Pomógł: 1827 Dołączył: 11.03.2014 Ostrzeżenie: (0%) ![]() ![]() |
Dziękuję wszystkim za zaangażowanie i pomysły.
-------------------- |
|
|
![]()
Post
#19
|
|
![]() Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
Można jeszcze taką magią:
Minus taki że nie może być dziur. Ten post edytował Pyton_000 6.08.2014, 12:00:22 |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 22.06.2025 - 01:14 |