如何在Django查询中传递Oracle优化提示
我在使用Oracle 11g数据库,想在Django的查询中使用Oracle提示。
我需要在Django中执行的SQL语句大概是这样的:
select /*+ ORDERED USE_NL(cd) */
*
from table1 d
inner join table2 cd on cd.id=d.id;
我不想使用Django的原生SQL查询,而是想把它整合进正常的Django ORM查询中,也就是像这样:
Table1.objects.all()
2 个回答
1
我也遇到过类似的问题。最后发现我只能通过“原始”的方式插入优化提示,举个例子就是:
Table1.objects.raw("""\
select /*+ ORDERED USE_NL(cd) */
d.*
from table1 d
inner join table2 cd on cd.id=d.id
""").all()
但是这样的话,你就不能使用通常的方法,比如“过滤”或者限制行数。所有的操作都得手动来做。
这是我的参考链接: https://docs.djangoproject.com/en/1.7/topics/db/sql/
4
编辑:看起来这种解决方案需要更多的测试,因为Oracle 对优化器提示的说明提到:如果包含提示的注释不紧跟在 DELETE、SELECT 或 UPDATE 关键字后面,Oracle 会忽略这些提示。(感谢 @swstephe 提醒这一点)。在这个解决方案中,第一个括号是多余的,因此优化器可能根本不会处理这个提示。
如果需要,你可以先检查 Django 在创建 SQL 时使用了哪些别名:
qs = Table1.objects.all()
用以下方式检查查询:
>>> print qs.query # or qs.query.sql_with_params()
SELECT "TABLE1"."ID",... FROM "TABLE1"
然后你可以通过使用Django 的 queryset extra 方法添加一个“额外”的虚拟列,列的定义中包含提示:
>>> qs = qs.extra(select={"dummy1" : '/*+ ORDERED USE_NL("TABLE1") */ 1 '}).all()
如果现在检查查询的样子,它看起来是这样的:
>>> print qs.query
SELECT (/*+ ORDERED USE_NL("TABLE1") */ 1) AS "DUMMY1", "TABLE1"."ID",
... FROM "TABLE1"
还有一些有用的参考资料:
- Django 数据库访问优化