3

我正在尝试使用此模型对 oracle 数据库进行查询:

class FCSTrunkValidation(Validation):
    card_transaction = models.CharField(max_length=10, db_column='card_trnsctn_seq', primary_key=True)
    card_number = models.CharField(max_length=16, db_column='card_num')
    use_date = models.CharField(max_length=14, db_column='use_date')
    device = models.ForeignKey('TrunkDevice', db_column='device_id')
    agency_id = models.CharField(max_length=3, db_column='agency_id')

这个查询:

# day is a datetime object
qs = FCSTrunkValidation.oracle_objects.all()
qs = qs.filter(use_date__startswith=day.strftime('%Y%m%d'))

当我这样做时,qs.count()我得到了这个:

...
  File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/query.py", line 93, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/query.py", line 108, in __len__
    self._result_cache.extend(self._iter)
  File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/query.py", line 317, in iterator
    for row in compiler.results_iter():
  File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 775, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 840, in execute_sql
    cursor.execute(sql, params)
  File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/backends/util.py", line 41, in execute
    return self.cursor.execute(sql, params)
  File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/backends/oracle/base.py", line 717, in execute
    six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
  File "/home/diegueus9/dev/odm/local/lib/python2.7/site-packages/django/db/backends/oracle/base.py", line 710, in execute
    return self.cursor.execute(query, self._param_generator(params))
DatabaseError: ORA-02395: exceeded call limit on IO usage

但是,如果我使用 squirrel 客户端执行查询,我得到了这个数字,那么 django 可能会执行额外的查询来引发错误?如何使计数与 django 一起工作?

我虽然使用原始 sql,但后来我在转义部分时遇到%LIKE问题

软件包版本

Python==2.7.4 Django==1.5.4 cx-Oracle==5.1.2 六==1.4.1

更新 20131023

根据@alko 的建议,我django.db.backends.oracle.base在第 709 行添加了一个打印语句,如下所示:

print query, self._param_generator(params)

然后我用 Squirrel 中的那些参数执行了那个查询,仍然得到了计数。

我的手动查询是:

select count(*) from TBAAD300 where AGENCY_ID=201 and USE_DATE LIKE '20130930%'

django 使用的查询是:

SELECT COUNT(*) FROM "TBAAD300" WHERE ("TBAAD300"."AGENCY_ID" = :arg0  AND "TBAAD300"."USE_DATE" LIKE TRANSLATE(:arg1 USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS) )

作为[u'201', u'20130930%']参数

然后我在 Squirrel 中执行了相同的查询,结果是 130410,但是当 django 执行时,会引发相同的错误,print语句打印的完整查询是:

ALTER SESSION SET NLS_TERRITORY = 'AMERICA' []
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF' TIME_ZONE = 'UTC' []
SELECT 1 FROM DUAL WHERE DUMMY LIKE TRANSLATE(:arg0 USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS) [u'X']
SELECT COUNT(*) FROM "TBAAD300" WHERE ("TBAAD300"."AGENCY_ID" = :arg0  AND "TBAAD300"."USE_DATE" LIKE TRANSLATE(:arg1 USING NCHAR_CS) ESCAPE TRANSLATE('\' USING NCHAR_CS) ) [u'201', u'20130930%']
4

1 回答 1

0

Oracle 是您的产品数据库吗?ORA-02395 表示 IO 限制,https: //forums.oracle.com/thread/655458 ,您的查询似乎count()会导致对 db 中的大表进行全面扫描,并限制每个查询的块读取。

我建议重新考虑您的数据模型,您可以使用DateFieldforuse_date字段并将查询替换为filter(use_date__gte = ..., use_date___lte = ...)? 在这种情况下,您可以通过在 use_date 字段上添加索引来显着提高性能和 IO 使用率,因为 count 和类似的查询可以在适当的情况下使用它。

更新(在此处添加到精细格式 SQL)

您的 Oracle DBMS 版本是多少?您是否在相同的用户凭据下运行语句?您的用户的资源限制是什么(会有所帮助)。

要检查资源消耗指标是什么,您还可以在 sql 客户端中运行以下命令:

exec runstats_pkg.rs_start;
<YOUR statement>
exec runstats_pkg.rs_stop;
select * from stats where name like '%session logical reads%';
select * from stats where name like '%consistent gets%';

执行计划也可能很方便

set autotrace on;
<YOUR STATEMENT>
set autotrace off;

如此处所述

于 2013-10-22T23:00:54.157 回答