E se facessi una select random escludendo i record con una IN? (Mi pare chi si chiami così quell'istruzione che serve a controllare di prendere roba presa già da un'altra parte, o di non farlo!)
E se facessi una select random escludendo i record con una IN? (Mi pare chi si chiami così quell'istruzione che serve a controllare di prendere roba presa già da un'altra parte, o di non farlo!)
I dilettanti costruirono l'Arca, i professionisti il Titanic!
3 domande.
La selezione delle immagini vale per tutti gli utenti che si collegano o ognuno puo' vedere differenti immagini ?
Mettiamo,che tu abbia un sistema per ricavare le immagini come vuoi. Come fai per risettare quando sono state tutte scelte ?
Quando e come avviene la selezione ?
Ridatemi i miei 1000 posts persi !!!!
Non serve a nulla ottimizzare qualcosa che non funziona.
Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr
Non ho ben capito cosa c'entrino le immagini. Comunque il gruppo di record che devo tirare fuori è singolo per una persona.
Ogni persona seleziona un numero arbitrario (che va da 10 a 70) e in una selezione non devono essere ripetuti mai.
Se successivamente lo stesso utente fa un'altra selezione possono essere anche gli stessi 70 di quella precedente ma ogni utente in ogni estrazione non deve avere due righe uguali!
Pensavo di fare così:
SELECT * FROM tabella WHERE idutente=X AND idestrazione=Y
ORDER BY RAND() LIMIT 0,1 NOT IN (SELECT * FROM tabella WHERE idutente=X AND idestrazione=Y)
poi fare un INSERT e ripetere la cosa.
Fare una cosa simile per 70 volte è troppo esoso, secondo te?
(prendi con le pinze la sintassi, vado a memoria data l'ora tarda! )
I dilettanti costruirono l'Arca, i professionisti il Titanic!
Io non ci capisco piu niente ......
"70" sono i record estratti per ogni singola estrazione oppure sono le estrazioni ????
"X" nel #1 era il numero di record estratti adesso invece è il "idutente"
"Y" che ci salta fuori adesso sembrerebbe il "idestrazione" registrato in tabella
ma se la estrazione la fai in questo momento con un clik puoi gia avere il suo idestrazione in tabella ???
..... ma ogni utente in ogni estrazione non deve avere due righe uguali! ......
No non saranno mai perche anche se 2 random fossero uguali si "accoppierebbero" a record diversi,
tu estrai il record quindi quello non puo assolutamente essere duplicato
Potrebbe invece succederti che (ipotizziano che fai "... LIMIT 20 ...") ti estrae 21 record nel caso che il 20° e il 21° random siano uguali, ma questo lo puoi facilmente risolvere,
Non entro pero in questo dettaglio fino a che non capisco bene cosa c'è a monte
Facci sapere
.
Ultima modifica di nman; 01-05-2017 a 07:26
+1
Bisogna anche pensare al fatto che se x utenti sono collegati nello stesso momento e fanno una richiesta contemporeneamente le loro richieste saranno eseguite in parallele con quindi una grande probabilità di selezione degli stessi record in parte.
Per ovviare cio' bisogna vedere CRON che esegue php in batch e le code lavori che consentono di eseguire le richieste l'una dopo l'altra.
Ridatemi i miei 1000 posts persi !!!!
Non serve a nulla ottimizzare qualcosa che non funziona.
Cerco il manuale dell'Olivetti LOGOS 80B - www.emmella.fr
SELECT * FROM tabella WHERE idutente=X AND idestrazione=Y
ORDER BY RAND() LIMIT 0, Z
Z è il numero di record da tirare fuori e lo puoi valorizzare con la scelta dell'utente
e ti posso assicurare che nel recordset per ciascuna esecuzione della query NON troverai mai due righe uguali (a meno che le righe uguali non ce le abbia tu nel DB...)
mica serve sempre fare nested query per ottenere un risultato. l'unico problema che potresti avere è un decadimento delle prestazioni nel caso di numerosi record, ma dato che filtri già per idUtente e idEstrazione (che non capisco cosa sia...) non credo avrai molti problemi (a meno che non ci siano veramente migliaia di record per ogni idUtente ed idEstrazione...)
Allora cerco di fare un po' di chiarimenti.
un utente si collega al sito, sceglie il numero totale di record (che va da 10 a 70) e fa un'estrazione di questi record.
Ovviamente ho l'id perché nella tabella "estrazione" creo la riga e subito dopo creo i vari record nella tabella "righeestratte".
Quindi posso tranquillamente usae l'id.
L'utente che si collega non deve avere righe ripetute. Neanche una delle (minimo) 10 o (massimo) 70.
Se due utenti fanno estrazioni diverse allora le righe possono essere ripetute.
Due utenti possono avere le stesse 70 righe estratte, se sono in due estrazione isolate, va benissimo!
Nella singola estrazione non devo avere doppioni, tutto qua! E devo esserne assolutamente certo!
Claksu il tuo discorso è un discorso probabilistico? Oppure la funzione è documentata così?
Io non devo avere neanche lo 0,00000001% di possibilità di avere record uguali nella stessa estrazione.
Il problema delle prestazioni non si pone a quanto capisco dato che al massimo ne faccio 70 in una sola volta!
Grazie a tutti comunque
perdonatemi ma quando dite #1 e #2 vi riferite ai miei messaggi? Ve lo chiedo perché non mi è mai capitato di leggere questo sistema di riferirsi ai post!
I dilettanti costruirono l'Arca, i professionisti il Titanic!
Schematizzo la struttura del database
tabellla utenti:
idutente, nomeutente
tabella archivio
idarchivio, contenuto
tabella
estrazioni
idestrazione
tabella
righeestratte
idestrazione,idutente,idarchivio
L'utente si logga, seleziona il numero N totale di righe e crea l'estrazione:
1 - aggiungo una riga in estrazione
2 - prendo l'id della nuova riga
3 - ESTRAGGO N righe da archivio ASSOLUTAMENTE non ripetute
4 - le inserisco in righeestratte
I dilettanti costruirono l'Arca, i professionisti il Titanic!
niente di probabilistico, semplice conoscenza di come viene composto il recordset di una query
tu esegui la tua query per il tuo utente, senza rand() otterrai questo:
- record 1
- record 2
- ... (fino all'esaurimento dei record restituiti dalla query)
- record n
esegui la stessa query due volte e avrai:
- record 50
- record 3
- ... (in ordine random fino all'esaurimento dei record restituiti dalla query)
- record rand(n)
- record 100
- record 9
- ... (in ordine fino all'esaurimento dei record restituiti dalla query)
- record n
tutte e tre le query di cui sopra restituiscono sempre lo stesso numero di record (chiamiamolo T)
ad ogni esecuzione, l'ordine dei record cambia in base a rand(), che non so esattamente che algoritmo usi ma presumo che tenda ad una distribuzione normale o gaussiana
ora, se tu decidi di prendere un sottoinsieme di T ad ogni esecuzione e dato che la query non si inventa nuovi record, otterrai un insieme di record univoci
il LIMIT viene eseguito sul recordset totale generato, quindi prima vengono calcolati i filtri (WHERE, HAVING, GROUP BY, ...), poi si fa l'ordinamento e da ultimo si esegue il LIMIT.
Se hai mille record per dei dati parametri, la query prima del limit si completerà in un certo numero di frazioni di tempo (millisecondi, secondi, ...)
Se hai un miliardo di record per gli stessi parametri, la query prima del LIMIT si completerà in un numero di frazioni di tempo sicuramente maggiore, dato che comunque esegue attività di computazione "pesanti" per il RAND() sui record.
Nel secondo caso, miliardo di record, si usano altre soluzioni
bene!
L'archivio sarà dell'ordine delle migliaia di record. Conto di avere circa 10000 righe tra cui selezionare le 10-70 di ogni estrazione e col tempo può aumentare al massimo di 2-3000 righe.
Dovrebbe essere una soluzione valida, quindi?
L'esempio con la query nested è sbagliato perché meno performante, inutilmente più complesso oppure non fa ciò che serve a me?
I dilettanti costruirono l'Arca, i professionisti il Titanic!