Prima sugestie a luiradeep Adiga, ORDER BY NEWID(), este bună și este ceva ce am folosit în trecut din acest motiv.

Aveți grijă cu utilizarea RAND() – în multe contexte este executată o singură dată pe instrucțiune, astfel încât ORDER BY RAND() nu va avea niciun efect (deoarece obțineți același rezultat din RAND() pentru fiecare rând).

De exemplu:

SELECT display_name, RAND() FROM tr_person

returnează fiecare nume din tabelul nostru de persoane și un număr „aleatoriu”, care este același pentru fiecare rând. Numărul variază de fiecare dată când executați interogarea, dar este același pentru fiecare rând de fiecare dată.

Pentru a arăta că același lucru se întâmplă și cu RAND() folosit într-o clauză ORDER BY, încerc:

SELECT display_name FROM tr_person ORDER BY RAND(), display_name

Rezultatele sunt în continuare ordonate după nume, ceea ce indică faptul că câmpul de sortare anterior (cel care se așteaptă să fie aleatoriu) nu are niciun efect, deci se presupune că are întotdeauna aceeași valoare.

Ordonarea după NEWID() funcționează totuși, deoarece dacă NEWID() nu ar fi reevaluat întotdeauna scopul UUID-urilor ar fi rupt atunci când se inserează multe rânduri noi într-un singur statemnt cu identificatori unici ca și cheie, așa că:

SELECT display_name FROM tr_person ORDER BY NEWID()

ordonează numele „aleatoriu”.

Alte SGBD-uri

Cele de mai sus sunt valabile pentru MSSQL (cel puțin 2005 și 2008, și dacă îmi amintesc bine și 2000). O funcție care returnează un nou UUID ar trebui să fie evaluată de fiecare dată în toate SGBD-urile NEWID() este sub MSSQL, dar merită să verificați acest lucru în documentație și/sau prin propriile teste. Comportamentul altor funcții cu rezultat arbitrar, cum ar fi RAND(), este mai probabil să varieze de la un SGBD la altul, așa că, din nou, verificați documentația.

De asemenea, am văzut că ordonarea valorilor UUID este ignorată în unele contexte, deoarece BD presupune că tipul nu are o ordonare semnificativă. Dacă considerați că acesta este cazul, transformați în mod explicit UUID-ul într-un tip de șir de caractere în clauza de ordonare sau înfășurați o altă funcție în jurul acestuia, cum ar fi CHECKSUM() în SQL Server (este posibil să existe o mică diferență de performanță și din această cauză, deoarece ordonarea se va face pe valori de 32 de biți, nu pe cele de 128 de biți, deși vă las să testați dacă beneficiul acestui lucru depășește costul de a rula CHECKSUM() pentru fiecare valoare în parte).

Nota secundară

Dacă doriți o ordonare arbitrară, dar oarecum repetabilă, ordonați după un subset relativ necontrolat al datelor din rândurile propriu-zise. De exemplu, oricare dintre acestea va returna numele într-o ordine arbitrară, dar repetabilă:

Ordonarea arbitrară dar repetabilă nu este de multe ori utilă în aplicații, deși poate fi utilă la testare dacă doriți să testați un cod pe rezultate într-o varietate de ordine, dar doriți să puteți repeta fiecare execuție în același mod de mai multe ori (pentru a obține rezultate medii de sincronizare pe parcursul mai multor execuții sau pentru a testa dacă o corecție pe care ați făcut-o la cod elimină o problemă sau o ineficiență evidențiată anterior de un anumit set de rezultate de intrare sau doar pentru a testa dacă codul dumneavoastră este „stabil”, în sensul că returnează același rezultat de fiecare dată dacă i se trimit aceleași date într-o anumită ordine).

Acest truc poate fi folosit, de asemenea, pentru a obține rezultate mai arbitrare din funcții, care nu permit apeluri nedeterministe precum NEWID() în interiorul corpului lor. Din nou, acest lucru nu este ceva care este probabil să fie adesea util în lumea reală, dar ar putea fi util dacă doriți ca o funcție să returneze ceva aleatoriu și „aleatoriu” este suficient de bun (dar aveți grijă să vă amintiți regulile care determină momentul în care funcțiile definite de utilizator sunt evaluate, adică, de obicei, doar o singură dată pe rând, sau este posibil ca rezultatele dvs. să nu fie cele pe care le așteptați/solicitați).

Performanță

Cum subliniază EBarr, pot exista probleme de performanță cu oricare dintre cele de mai sus. Pentru mai mult de câteva rânduri, este aproape garantat că veți vedea ieșirea spooled în tempdb înainte ca numărul solicitat de rânduri să fie citit înapoi în ordinea corectă, ceea ce înseamnă că, chiar dacă căutați primele 10 rânduri, s-ar putea să constatați că o scanare completă a indexului (sau, mai rău, o scanare a tabelului) se întâmplă împreună cu un bloc uriaș de scriere în tempdb. De aceea, poate fi de o importanță vitală, ca în cazul majorității lucrurilor, să efectuați o analiză comparativă cu date realiste înainte de a utiliza acest lucru în producție.

admin

Lasă un răspuns

Adresa ta de email nu va fi publicată.

lg