如何在Django查询中传递Oracle优化提示

2 投票
2 回答
1097 浏览
提问于 2025-04-30 20:19

我在使用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"

还有一些有用的参考资料:

撰写回答