Ich baue eine Django-Website mit einem Oracle-Backend, und ich beobachte sehr langsame Leistung, auch wenn ich einfache Lookups auf dem Primärschlüssel durchführe. Derselbe Code funktioniert sehr schnell, wenn die gleichen Daten in MySQL geladen werden.Schlechte Leistung von Django ORM mit Oracle
Was könnte der Grund für die schlechte Leistung sein? Ich habe den Verdacht, dass das Problem mit der Verwendung von Oracle-Bindeparametern zusammenhängt, aber dies ist möglicherweise nicht der Fall.
Django Modell (eine Testtabelle mit ~ 6.200.000 Zeilen)
from django.db import models
class Mytable(models.Model):
upi = models.CharField(primary_key=True, max_length=13)
class Meta:
db_table = 'mytable'
Django ORM (dauert ~ 1s)
from myapp.models import *
r = Mytable.objects.get(upi='xxxxxxxxxxxxx')
Raw Abfrage mit bind Parameter (nimmt ~ 1s)
cursor.execute("SELECT * FROM mytable WHERE upi = %s", ['xxxxxxxxxxxxx'])
row = cursor.fetchone()
print row
Raw Abfrage ohne Bind Parameter (momentane)
cursor.execute("SELECT * FROM mytable WHERE upi = 'xxxxxxxxxxxxx'")
row = cursor.fetchone()
print row
Meine Umgebung
- Python 2.6.6
- Django 1.5.4
- cx-Oracle 5.1.2
- Oracle 11g
Wenn die Oracle-Datenbank verbinden ich angeben:
'OPTIONS': {
'threaded': True,
}
Jede Hilfe sehr geschätzt wird.
[Update] habe ich einige weitere Tests die debugsqlshell
Werkzeug aus der Django-Debug-Toolbar verwenden.
# takes ~1s
>>>Mytable.objects.get(upi='xxxxxxxxxxxxx')
SELECT "Mytable"."UPI"
FROM "Mytable"
WHERE "Mytable"."UPI" = :arg0 [2.70ms]
Dies legt nahe, dass die Oracle Django bind Parameter verwendet, und die Abfrage selbst ist sehr schnell, aber das entsprechende Objekt Python Erstellung dauert sehr lange Zeit.
Nur um zu bestätigen, habe ich die gleiche Abfrage mit cx_Oracle (beachten Sie, dass die cursor
in meiner ursprünglichen Frage ist die Django cursor).
import cx_Oracle
db= cx_Oracle.connect('connection_string')
cursor = db.cursor()
# instantaneous
cursor.execute('SELECT * from mytable where upi = :upi', {'upi':'xxxxxxxxxxxxx'})
cursor.fetchall()
Was könnte Django ORM verlangsamen?
[Update 2] Wir haben die Datenbankleistung von der Oracle-Seite betrachtet, und es stellt sich heraus, dass der Index nicht verwendet wird, wenn die Abfrage von Django kommt. Irgendwelche Ideen, warum das der Fall sein könnte?
Sie den Index für das Nachschlag-Feld überprüfen Gab es in db? – esauro
Wenn ich die Tabelle in SQL Developer überprüfe, sehe ich, dass es einen gültigen normalen Index für diese Spalte gibt. – apetrov
Was passiert, wenn Sie die zwei Versionen in SQL Developer ausführen und sich die Abfragepläne unterscheiden (verwenden Sie die Schaltflächen Plan erklären oder AutoTrace verwenden)? Für Bind-Variablen verwenden Sie SELECT * FROM meine Tabelle WHERE upi =: s und SQL Developer wird Sie nach dem Wert fragen. –