Domanda

So che se eseguo questa query

select top 100 * from mytable order by newid()
.

Otterrà 100 record casuali dalla mia tabella.

Tuttavia, sono un po 'confuso su come funziona, dal momento che non vedo newid() nell'elenco select.Qualcuno può spiegare?C'è qualcosa di speciale in generale newid() qui?

È stato utile?

Soluzione

.

So cosa fa NewId (), sono solo cercando di capire come avrebbe aiutato nella selezione casuale. È così (1) L'istruzione SELECT selezionerà Tutto da mytable, (2) per ciascuno riga selezionata, virata su a uniquecentificatore generato da newid (), (3) Ordina le righe di questo univocoIdentifier e (4) Scegli il Top 100 dalla lista ordinata?

Sì. Questo è praticamente corretto (tranne che non è necessariamente necessario ordinare tutti le righe). Puoi verificarlo guardando il piano di esecuzione effettivo.

SELECT TOP 100 * 
FROM master..spt_values 
ORDER BY NEWID()
.

L'operatore Scalare calcolatore aggiunge la colonna NEWID() su ciascuna riga (2506 nella tabella nella mia query di esempio), le righe nella tabella sono ordinate per questa colonna con la top 100 selezionata.

SQL Server non è effettivamente necessario ordinare l'intero set da Positions 100 Down in modo da utilizzare un operatore di ordinamento TOP N che tenta di eseguire l'intera operazione di ordinamento in memoria ( Per piccoli valori di N )

 Plan

Altri suggerimenti

In generale funziona in questo modo:

    .
  • Tutte le righe da mytable è "looped"
  • newid () viene eseguito per ogni riga
  • Le righe sono ordinate in base al numero casuale da NEWID ()
  • 100 prima riga sono selezionati

La chiave qui è la nuova funzione, che genera un identificatore univoco globalmente (GUID) in memoria per ogni riga. Per definizione, il GUID è unico e abbastanza casuale; Quindi, quando ti ordina per quel GUID con la clausola dell'Ordine, ottieni un ordine casuale delle righe nella tabella. Prendendo la top 10 percento (o qualsiasi percentuale desiderata) ti darà un campionamento casuale delle righe nel tavolo.

la nuova query è proposta; È semplice e funziona molto bene per tavoli piccoli. Tuttavia, la nuova query ha un grande inconveniente quando lo si utilizza per tavoli di grandi dimensioni. L'ordine per clausola provoca copiare tutte le righe nella tabella nel database TEMPDB, dove vengono ordinate. Ciò causa due problemi: L'operazione di ordinamento di solito ha un costo elevato ad esso associato. L'ordinamento può utilizzare un sacco di I / O del disco e può funzionare per un lungo periodo. Nello scenario peggiore, TEMPDB può esaurirsi lo spazio. Nello scenario migliore-caso, TEMPDB può prendere una grande quantità di spazio su disco che non verrà mai recuperato senza un comando di shrink manuale. Ciò di cui hai bisogno è un modo per selezionare le righe in modo casuale che non utilizzerà Tempdb e non verrà molto più lento quando la tabella diventa più grande. Ecco una nuova idea su come farlo:

SELECT * FROM master..spt_values
  WHERE (ABS(CAST(
  (BINARY_CHECKSUM(*) *
  RAND()) as int)) % 100) < 10
.

L'idea di base dietro questa query è che vogliamo generare un numero casuale compreso tra 0 e 99 per ogni riga nella tabella, quindi scegliere tutte quelle righe il cui numero casuale è inferiore al valore della percentuale specificata. In questo esempio, vogliamo circa il 10 percento delle righe selezionate a caso; Pertanto, scegliamo tutte le righe il cui numero casuale è inferiore a 10.

come msdn dice:

.

newid () crea un valore unico di tipo univocoIdentifier.

E la tabella verrà ordinata da questo valori casuali.

Usa select top 100 randid = newid(), * from mytable order by randid Sarai chiarito quindi ..

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top