Tôi đang xây dựng trang web Django với chương trình phụ trợ của Oracle và tôi quan sát hiệu suất rất chậm ngay cả khi thực hiện tra cứu đơn giản trên khóa chính. Cùng một mã hoạt động rất nhanh khi cùng một dữ liệu được tải trong MySQL.Hiệu suất kém của Django ORM với Oracle
Điều gì có thể là lý do cho hiệu suất kém? Tôi có một nghi ngờ rằng vấn đề có liên quan đến việc sử dụng các tham số liên kết Oracle, nhưng điều này có thể không phải là trường hợp.
Django mô hình (một bảng thử nghiệm với ~ 6.200.000 hàng)
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 (mất ~ 1s)
from myapp.models import *
r = Mytable.objects.get(upi='xxxxxxxxxxxxx')
truy vấn liệu với các thông số ràng buộc (mất ~ 1s)
cursor.execute("SELECT * FROM mytable WHERE upi = %s", ['xxxxxxxxxxxxx'])
row = cursor.fetchone()
print row
truy vấn liệu không có ràng buộc thông số (tức thời)
cursor.execute("SELECT * FROM mytable WHERE upi = 'xxxxxxxxxxxxx'")
row = cursor.fetchone()
print row
Môi trường của tôi
- Python 2.6.6
- Django 1.5.4
- cx-Oracle 5.1.2
- Oracle 11g
Khi kết nối với cơ sở dữ liệu Oracle tôi chỉ định:
'OPTIONS': {
'threaded': True,
}
Bất kỳ trợ giúp sẽ được đánh giá cao.
[Cập nhật] Tôi đã thực hiện thêm một số thử nghiệm bằng công cụ debugsqlshell
từ thanh công cụ gỡ lỗi Django.
# takes ~1s
>>>Mytable.objects.get(upi='xxxxxxxxxxxxx')
SELECT "Mytable"."UPI"
FROM "Mytable"
WHERE "Mytable"."UPI" = :arg0 [2.70ms]
Điều này cho thấy Django sử dụng tham số liên kết Oracle và truy vấn rất nhanh, nhưng việc tạo đối tượng Python tương ứng mất một thời gian rất dài.
Chỉ cần xác nhận, tôi đã chạy cùng một truy vấn bằng cách sử dụng cx_Oracle (lưu ý rằng cursor
trong câu hỏi ban đầu của tôi là 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()
Điều gì có thể làm chậm xuống Django ORM?
[Cập nhật 2] Chúng tôi đã xem xét hiệu suất cơ sở dữ liệu từ phía Oracle và chỉ ra rằng chỉ mục này không được sử dụng khi truy vấn đến từ Django. Bất kỳ ý tưởng tại sao điều này có thể là trường hợp?
Bạn có kiểm tra các chỉ số cho lĩnh vực tra cứu tồn tại trong db? – esauro
Khi tôi kiểm tra bảng trong SQL Developer, tôi thấy rằng có một chỉ số bình thường hợp lệ trên cột đó. – apetrov
Điều gì sẽ xảy ra nếu bạn chạy 2 phiên bản trong Nhà phát triển SQL và các kế hoạch truy vấn khác nhau (sử dụng các nút Giải thích Kế hoạch hoặc Tự động)? Đối với các biến liên kết, sử dụng 'SELECT * FROM mytable WHERE upi =: s' và SQL Developer sẽ nhắc bạn về giá trị. –