标题几乎说明了一切。我从Django 1.3升级到1.5.12,现在Oracle查询速度慢了10倍。据DBA称,查询通过Oracle Developer的运行时间不到1/2秒。
以下是型号:
class EsdPerson(models.Model):
'''A partial user profile from the external read-only ESD database.
Users may be indexed by ppid or netid.'''
_id = models.AutoField(primary_key=True, db_column='prsn_i', editable=False)
ppid = models.CharField(max_length=8, db_column='prsn_i_pblc',
help_text="public person id/directory key")
directory_name = models.CharField(max_length=75, db_column='prsn_n_full_dtry',
help_text="full name in the online directory")
ad_name = models.CharField(max_length=75, db_column='prsn_n_dspl_acdr',
help_text="name in Active Directory")
firstmid_name = models.CharField(max_length=20, db_column='prsn_n_fm_dtry',
help_text="first and middle name in the online directory")
last_name = models.CharField(max_length=25, db_column='prsn_n_last_dtry',
help_text="last name in the online directory")
name_suffix = models.CharField(max_length=15, db_column='prsn_n_sufx_dtry',
help_text="honorary or other name suffix in the online directory")
title = models.CharField(max_length=70, db_column='prsn_e_titl_dtry',
help_text="position title in the online directory")
phone = models.CharField(max_length=12, db_column='prad_a_tlph_empe_fmtt',
help_text="phone number in the online directory")
fax = models.CharField(max_length=12, db_column='prad_a_fax_empe_fmtt',
help_text="fax number in the online directory")
department_id = models.CharField(max_length=10, db_column='dprt_c',
help_text="identifying code of the department the user works in")
department_name = models.CharField(max_length=40, db_column='dprt8dtry_n',
help_text="human-readable name of the department the user works in")
division_code = models.CharField(max_length=10, db_column='dvsn_i',
help_text="identifying code of the division the user works in")
division_name = models.CharField(max_length=40, db_column='dvsn8dtry_n',
help_text="human-readable name of the division the user works in")
mailstop_code = models.CharField(max_length=12, db_column='mlst_i',
help_text="identifying code of the user's mailstop")
mailstop_name = models.CharField(max_length=30, db_column='mlst_n',
help_text="human-readable name of the user's mailstop")
netid = models.CharField(max_length=8, db_column='logn8ntwr_i',
help_text="network login") # always all-caps
internet_suppressed = YesNoBooleanField(db_column='prsn_f_sprs_intt',
help_text="suppress user's directory information to off-campus clients")
directory_suppressed = YesNoBooleanField(db_column='prsn_f_sprs_dtry',
help_text="suppress user's directory information to all clients")
information_suppressed = YesNoBooleanField(db_column='prsn_f_sprs_infr',
help_text="no reference allowed to user")
faculty_flag = YesNoBooleanField(max_length=1, db_column='empe_f_fclt',
help_text="user is a faculty member")
email = models.CharField(max_length=100, db_column='emad_n',
help_text="user's primary email address")
email_forward = models.CharField(max_length=100, db_column='emad8frwd_n',
help_text="internal or external forwarding address for email")
# default manager
objects = models.Manager()
faculty = EsdFacultyManager()
'custom object manager for faculty persons only'
# choice meanings per email from esd team
EMPLOYEE_STATUS_CHOICES = (
('A', 'active'),
('D', 'deceased'),
('L', 'on leave'),
('O', 'on-boarding'), # ESDs term. not sure what it means
('P', 'sponsored'),
('T', 'terminated'),
)
employee_status = models.CharField(max_length=1, choices=EMPLOYEE_STATUS_CHOICES,
db_column='emjo_c_stts_empe')
# choice meanings per email from esd team
PERSON_TYPE_CHOICES = (
('A', 'administrative'),
('B', 'student/staff'),
('C', 'staff/student'),
('E', 'staff'),
('F', 'faculty'),
('J', 'EU job eligible'),
('O', 'student applicant'),
('P', 'sponsored'),
('R', 'retired'),
('S', 'student'),
('U', 'unknown'),
('X', 'pre-start'),
)
person_type = models.CharField(max_length=1, db_column='prsn_c_type')
class Meta:
db_tablespace = 'esdv'
# oracle tablespace requires this db_table syntax as of django
# 1.3.1. mysql interprets it as a table name with quotes and a
# period in it.
db_table = '"esdv"."v_oem_fclt"'
managed=False
def __unicode__(self):
return '%s (%s)' % (self.ppid, self.netid)
@property
def department_shortname(self):
if ':' in self.department_name:
return self.department_name[self.department_name.find(':')+1:].strip()
return self.department_name
def profile(self):
'''Find the :class:`UserProfile` corresponding to this
:class:`EsdPerson`.
'''
return UserProfile.objects.get(user__username=self.netid.lower())
def has_profile_page(self):
'''Return ``True`` if the user should have a public-facing web
profile on the site, ``False`` if not. Currently requires
Faculty status.
'''
return self.person_type == 'F'
# additional field mappings for solr indexing
@property
def id(self):
'Id for use as Solr common id - `ppid:P####`, based on :attr:`ppid`.'
return 'ppid:%s' % self.ppid
_first_name = None
@property
def first_name(self):
'''First and middle name for indexing in Solr.
Uses :attr:`firstmid_name` when available; if empty, attempts
to infer first name based on :attr:`last_name` and
:attr`ad_name`.
'''
if self._first_name is None:
# if first-middle directory name is available, use it
if self.firstmid_name:
self._first_name = self.firstmid_name
# otherwise, if both last name and ad name are available and match,
# infer first name from ad name (ad name format: lastname, first middle)
elif self.last_name and self.ad_name and self.ad_name.startswith(self.last_name):
self._first_name = self.ad_name[len(self.last_name):].strip(' ,')
return self._first_name
@property
def username(self):
'Lower-case form of :attr:`netid`, for indexing in Solr.'
return self.netid.lower()
record_type = 'accounts_esdperson'
'record type for Solr index, to distinguish from other indexed content'
# following django contenttype convention: app_label, model
@property
def division_dept_id(self):
'''Delimited field with division name and code, along with
department name and id, so Departments and Divisions can be
used with Solr facets but linked to the appropriate code or
id. Uses the shortened name of the department.'''
return '|'.join([self.division_name, self.division_code,
self.department_shortname, self.department_id])
@staticmethod
def split_department(division_dept_id):
div, div_code, dept, dept_id = division_dept_id.split('|')
return {
'division_name': div,
'division_code': div_code,
'department_name': dept,
'department_id': dept_id,
}
@property
def affiliations(self):
try:
profile = self.profile()
except UserProfile.DoesNotExist:
return []
return profile.position_set.all()
def index_data(self):
'''Indexing information for this :class:`EsdPerson` instance
in a format that :meth:`sunburnt.SolrInterface.add` can
handle. If this person is internet or directory suppressed
and does not have a local profile overridding that
suppression, returns a dictionary with minimal information to
be indexed. Otherwise, returns the item itself for
:mod:`sunburnt` to inspect and index all fields that match
fields in the Solr schema.
:returns: dict or :class:`EsdPerson`
'''
if self.internet_suppressed or self.directory_suppressed:
try:
profile = self.profile()
except UserProfile.DoesNotExist:
profile = None
# if profile does not exist or suppression override is not set,
# return *minimal* information
if profile is None or profile and not profile.show_suppressed:
return {
'id': self.id,
'ppid': self.ppid,
'record_type': self.record_type,
# info required for co-author lookup
'username': self.username,
'ad_name': self.ad_name,
'first_name': self.first_name,
'last_name': self.last_name,
}
return self
答案 0 :(得分:0)
使用最新版本的Django正确配置数据库,否则会给出版本更新的错误。
答案 1 :(得分:0)
根据我和DBA所做的调查,看起来Django 1.5处理索引和/或绑定变量的方式与Django 1.3不同(我知道这不是很多帮助或解释)。
DBA添加了三个索引,道歉我没有前两个代码,但它们似乎没有任何影响。他们说的第三个是基于函数的索引就行了。这是代码:
CREATE INDEX "ESD"."CSTM_FBINDX_LOGN8NTWR" ON "ESD"."CSTM" (TO_NCHAR("LOGN8NTWR_I"))
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 20971520 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SHAREDATA" ;
analyze index ESD.CSTM_FBINDX_LOGN8NTWR validate structure;