Ho avuto una query che è stata eseguita bene per circa 2 anni. La tabella del database ha circa 50 milioni di righe e sta crescendo lentamente. Questa settimana scorsa, una delle mie domande è stata quella di tornare quasi istantaneamente a prendere ore per correre.Query semplice che funziona da anni, poi improvvisamente molto lento
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)).latest('id')
Ho ristretto la query lenta al modello di rango. Sembra avere qualcosa a che fare con l'uso del metodo latest(). Se chiedo solo un queryset, restituisce immediatamente un queryset vuoto.
#count returns 0 and is fast
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)).count() == 0
Rank.objects.filter(site=Site.objects.get(profile__client=client, profile__is_active=False)) == [] #also very fast
Ecco i risultati dell'esecuzione di EXPLAIN. http://explain.depesz.com/s/wPh
e spiegare analizza: http://explain.depesz.com/s/ggi
ho provato l'aspirapolvere sul tavolo, nessun cambiamento. Esiste già un indice nel campo "sito" (ForeignKey).
Stranamente, se eseguo questa stessa query per un altro client che ha già oggetti di rango associati al suo account, la query restituisce molto rapidamente ancora una volta. Quindi sembra che questo sia solo un problema quando non sono oggetti Rank per quel client.
Qualche idea?
Versioni: Postgres 9.1, Django tronco 1.4 svn rev 17047
L'impostazione di un indice composto sul campo nel WHERE e il campo in ORDER BY hanno fatto il trucco. Si scopre che il pianificatore di query stava eseguendo la scansione dell'intero indice per l'ordinamento e quindi facendo il filtro. L'indice composto ha fatto il trucco. – erikcw