Oracle을 사용한 Django ORM의 성능 저하
저는 오라클 백엔드로 장고 웹사이트를 만들고 있는데, 기본 키에서 간단한 검색을 해도 성능이 매우 느립니다.MySQL에 동일한 데이터가 로드되면 동일한 코드가 매우 빠르게 작동합니다.
실적이 부진한 이유는 무엇일까요?문제가 Oracle bind parameter의 사용과 관련된 것이 아닌가 하는 의심이 들지만, 그렇지 않을 수도 있습니다.
장고 모형(~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'
장고 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
나의환경
- 파이썬 2.6.6
- 장고 1.5.4
- cx-오라클 5.1.2
- 오라클 11g
Oracle 데이터베이스에 연결할 때 다음을 지정합니다.
'OPTIONS': {
'threaded': True,
}
어떤 도움이라도 주시면 대단히 감사하겠습니다.
[업데이트] 나는 다음을 사용하여 몇 가지 테스트를 했습니다.debugsqlshell
장고 디버그 도구 모음의 도구입니다.
# takes ~1s
>>>Mytable.objects.get(upi='xxxxxxxxxxxxx')
SELECT "Mytable"."UPI"
FROM "Mytable"
WHERE "Mytable"."UPI" = :arg0 [2.70ms]
이는 Django가 Oracle bind parameter를 사용하고 쿼리 자체가 매우 빠르지만 해당 Python 개체를 생성하는 데 시간이 매우 오래 걸린다는 것을 의미합니다.
확인을 위해 cx_Oracle을 사용하여 동일한 쿼리를 실행했습니다.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()
장고 ORM의 속도를 늦추는 것은 무엇일까요?
[업데이트 2] 오라클 쪽에서 데이터베이스 성능을 살펴봤는데, 질의가 장고에서 올 때 인덱스를 사용하지 않는 것으로 나타났습니다.왜 이런 일이 벌어질지 짐작이 가십니까?
를 사용하면 성능 문제가 해결됩니다.
cursor.execute("SELECT * FROM mytable WHERE upi = TO_CHAR(%s)", ['xxxxxxxxxxxxx'])
DBA들과 함께 일을 해본 결과, 어떤 이유에서인지 장고get(upi='xxxxxxxxxxxx')
쿼리가 데이터베이스 인덱스를 사용하지 않았습니다.
다음을 사용하여 동일한 쿼리를 다시 작성한 경우filter(upi='xxxxxxxxxxxx')[:1].get()
, 질문이 빨랐습니다.
그get
쿼리는 정수 기본 키로만 빠릅니다(원래 질문에서 문자열이었습니다).
최종 솔루션
create index index_name on Mytable(SYS_OP_C2C(upi));
cx_Oracle과 Oracle에서 사용하는 문자 집합이 일치하지 않는 것 같습니다.C2C 인덱스를 추가하면 문제가 해결됩니다.
업데이트: 또한 Oracle의 VARCHAR2에서 NVARCHAR2로 전환하면 동일한 효과가 있으며 기능 인덱스 대신 사용할 수 있습니다.
다음은 저에게 도움이 된 몇 가지 유용한 토론 스레드입니다. http://comments.gmane.org/gmane.comp.python.db.cx-oracle/2940 http://comments.gmane.org/gmane.comp.python.db.cx-oracle/3049
언급URL : https://stackoverflow.com/questions/18978536/poor-performance-of-django-orm-with-oracle
'programing' 카테고리의 다른 글
Spring Boot에서 Tomcat JNDI JDBC 데이터 소스를 사용하는 방법 (0) | 2023.10.09 |
---|---|
Vim으로 Git commit 메시지 입력 문제 (0) | 2023.10.09 |
문자열을 더블로 변환하면 리터럴 더블과 같습니까? (0) | 2023.10.09 |
아마존 s3 버킷에서 파일을 삭제하는 방법? (0) | 2023.10.09 |
MySQL에 이미지를 저장할 PHP인가요, 아닌가요? (0) | 2023.10.09 |