support password django oracle orm sqlalchemy cx-oracle

django - password - sqlalchemy postgresql



Mal rendimiento de Django ORM con Oracle (2)

Después de trabajar con nuestros DBA, resultó que, por alguna razón, las consultas de Django get(upi=''xxxxxxxxxxxx'') no usaban el índice de la base de datos.

Cuando la misma consulta se reescribió utilizando filter(upi=''xxxxxxxxxxxx'')[:1].get() , la consulta fue rápida.

La consulta de get fue rápida solo con claves primarias de enteros (era cadena en la pregunta original).

SOLUCIÓN FINAL

create index index_name on Mytable(SYS_OP_C2C(upi));

Parece que hay una falta de coincidencia entre los juegos de caracteres utilizados por cx_Oracle y Oracle. Agregar el índice C2C corrige el problema.

ACTUALIZACIÓN : Además, cambiar a NVARCHAR2 desde VARCHAR2 en Oracle tiene el mismo efecto y se puede usar en lugar del índice funcional.

Aquí hay algunos hilos de discusión útiles que me ayudaron: http://comments.gmane.org/gmane.comp.python.db.cx-oracle/3049 http://comments.gmane.org/gmane.comp.python.db .cx-oracle / 2940

Estoy construyendo un sitio web de Django con un back-end de Oracle, y observo un rendimiento muy lento incluso cuando realizo búsquedas simples en la clave principal. El mismo código funciona muy rápido cuando se cargan los mismos datos en MySQL.

¿Cuál podría ser el motivo del bajo rendimiento? Tengo la sospecha de que el problema está relacionado con el uso de los parámetros de enlace de Oracle, pero este puede no ser el caso.

Modelo Django (una tabla de prueba con ~ 6,200,000 filas)

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 (toma ~ 1s)

from myapp.models import * r = Mytable.objects.get(upi=''xxxxxxxxxxxxx'')

Consulta sin procesar con parámetros de enlace (toma ~ 1s)

cursor.execute("SELECT * FROM mytable WHERE upi = %s", [''xxxxxxxxxxxxx'']) row = cursor.fetchone() print row

Consulta sin procesar sin parámetros de vinculación (instantánea)

cursor.execute("SELECT * FROM mytable WHERE upi = ''xxxxxxxxxxxxx''") row = cursor.fetchone() print row

Mi entorno

  • Python 2.6.6
  • Django 1.5.4
  • cx-Oracle 5.1.2
  • Oracle 11g

Cuando me conecto a la base de datos Oracle, especifico:

''OPTIONS'': { ''threaded'': True, }

Cualquier ayuda será apreciada.

[Actualizar] debugsqlshell algunas pruebas adicionales utilizando la herramienta debugsqlshell la debugsqlshell herramientas de depuración Django.

# takes ~1s >>>Mytable.objects.get(upi=''xxxxxxxxxxxxx'') SELECT "Mytable"."UPI" FROM "Mytable" WHERE "Mytable"."UPI" = :arg0 [2.70ms]

Esto sugiere que Django usa los parámetros de vinculación de Oracle, y la consulta en sí misma es muy rápida, pero crear el objeto Python correspondiente lleva mucho tiempo.

Solo para confirmar, ejecuté la misma consulta usando cx_Oracle (tenga en cuenta que el cursor en mi pregunta original es el 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()

¿Qué podría estar frenando Django ORM?

[Actualización 2] Revisamos el rendimiento de la base de datos desde el lado de Oracle, y resulta que el índice no se usa cuando la consulta proviene de Django. ¿Alguna idea de por qué este podría ser el caso?


Usar TO_CHAR(character) debería resolver el problema de rendimiento:

cursor.execute("SELECT * FROM mytable WHERE upi = TO_CHAR(%s)", [''xxxxxxxxxxxxx''])