Ho spiegato una situazione simile con file di testo normale su Grep un numero enorme di modelli da un file enorme. Molte persone lì hanno detto che dovrei, quindi ora sto migrando i miei dati su un database sqlite:
Ho un file da cui estraggo circa 10.000 pattern. Quindi controllo se il database non contiene tali schemi. In caso contrario, devo salvarli esternamente in file
per ulteriore elaborazione:
for id in $(grep ^[0-9] keys); do
if [[ -z $(sqlite3 db.sqlite "select id from main where id = $id") ]]; then
echo $id >>file
fi
done
Dato che sono nuovo di SQL, non sono riuscito a trovare un modo semplice per farlo. Inoltre, questo ciclo è inutile in quanto è 20 volte più lento di quello che ho ottenuto con awk
sull'URL menzionato.
Poiché il database è enorme, continua a crescere e eseguo questo ciclo molto frequentemente, è possibile renderlo più veloce?
Risposta accettata:
Per ogni pattern, stai invocando una nuova istanza di sqlite
programma che si collega nuovamente al database. È uno spreco. Dovresti creare una singola query che cerchi una qualsiasi delle chiavi, quindi eseguire quella query. I client di database sono bravi a eseguire query di grandi dimensioni.
Se le righe corrispondenti nelle keys
il file contiene solo cifre, quindi puoi creare la query come segue:
{
echo 'select id from main where id in (';
<keys grep -x '[0-9][0-9]*' | # retain only lines containing only digits
sed -e '1! s/^/, /' | # add ", " at the beginning of every line except the first
echo ');'
} | sqlite3 db.sqlite
Per dati di input più generali, ti viene l'idea:usa le trasformazioni del testo per creare una singola query di grandi dimensioni. Fai attenzione a convalidare il tuo input; qui ci assicuriamo che ciò che viene iniettato nella query sia sintatticamente valido. In realtà c'è un caso d'angolo nell'esempio sopra:se non c'è corrispondenza nel file, la sintassi SQL non è valida; se ciò dovesse accadere, dovrai trattare questo caso in modo speciale. Ecco un codice più complesso che si occupa del caso vuoto:
<keys grep -x '[0-9][0-9]*' |
if read first; then {
echo 'select id from main where id in (' "$first"
sed -e 's/^/, /'
echo ');'
} | sqlite3 db.sqlite
fi