Я создаю сайт Django с бэкэндом Oracle, и я наблюдаю очень медленную производительность даже при простых проверках первичного ключа. Тот же код работает очень быстро, когда одни и те же данные загружаются в MySQL.
В чем причина плохой работы? У меня есть подозрение, что проблема связана с использованием параметров привязки Oracle, но это может быть не так.
Модель Django (тестовая таблица с ~ 6 200 000 строк)
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 (занимает ~ 1 с)
from myapp.models import *
r = Mytable.objects.get(upi='xxxxxxxxxxxxx')
Необработанный запрос с параметрами привязки (занимает ~ 1 с)
cursor.execute("SELECT * FROM mytable WHERE upi = %s", ['xxxxxxxxxxxxx'])
row = cursor.fetchone()
print row
Необработанный запрос без параметров привязки (мгновенный)
cursor.execute("SELECT * FROM mytable WHERE upi = 'xxxxxxxxxxxxx'")
row = cursor.fetchone()
print row
Моя среда
- Python 2.6.6
- Django 1.5.4
- cx-Oracle 5.1.2
- Oracle 11g
При подключении к базе данных Oracle я указываю:
'OPTIONS': {
'threaded': True,
}
Любая помощь будет принята с благодарностью.
[Обновление]
Я провел некоторое тестирование с помощью инструмента debugsqlshell
с панели инструментов отладки Django.
# takes ~1s
>>>Mytable.objects.get(upi='xxxxxxxxxxxxx')
SELECT "Mytable"."UPI"
FROM "Mytable"
WHERE "Mytable"."UPI" = :arg0 [2.70ms]
Это говорит о том, что Django использует параметры привязки Oracle, а сам запрос выполняется очень быстро, но создание соответствующего объекта Python занимает очень много времени.
Просто для подтверждения, я выполнил тот же запрос, используя cx_Oracle (обратите внимание, что cursor
в моем исходном вопросе является курсором Django).
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()
Что может замедлить работу Django ORM?
[Обновление 2] Мы рассмотрели производительность базы данных со стороны Oracle, и выяснилось, что индекс не используется, когда запрос поступает из Django. Любые идеи, почему это может быть так?