sql - Oracle - 这个查询可以优化吗?
问题描述
我想获取一组行的最后一个日期。什么更高效:Query1 或 Query2:
查询1
select *
from(
select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234'
order by column_date desc) c
where rownum=1
查询2
select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234'
order by column_date desc
并在后端取第一行。
或者也许有另一种方法可以在 Oracle 中占据第一行?我知道通常子选择的性能很差。这就是我试图删除子选择的原因。
我试过了,但我没有得到预期的结果:
select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234' and rownum=1
order by column_date desc
解决方案
首先,您无法真正优化查询。查询总是由优化器重写,并且可能会根据有多少数据、索引等给出非常不同的结果。因此,如果您的查询速度很慢,则必须查看执行计划以了解发生了什么。如果您有一个不慢的查询,您不应该优化它。
子选择本身没有任何问题。正如 Wernfriend Domscheit 所建议的,这将为您提供最小的 column_date,我假设它位于 table2 中。
SELECT MIN( b.column_date )
FROM table1 a
INNER JOIN table2 b on a.column1 = b.column1
WHERE a.id= '1234'
这保证给你一个单行。如果您需要的不仅仅是日期字段,这将选择具有最短日期的行:
SELECT a.*, b.column_date
FROM table1 a
INNER JOIN table2 b on a.column1 = b.column1
WHERE a.id= '1234'
AND b.column_date = ( SELECT MIN( b2.column_date ) FROM table2 b2 )
但是,如果您的 column_date 不是唯一的,则可能会返回多行。如果可能的话,您将需要数据中的某些内容来区分要选择的行。这保证给你一行:
SELECT * FROM (
SELECT a.*, b.column_date
FROM table1 a
INNER JOIN table2 b on a.column1 = b.column1
WHERE a.id= '1234'
AND b.column_date = ( SELECT MIN( b2.column_date ) FROM table2 b2 )
ORDER BY a.some_other_column
)
WHERE ROWNUM = 1
在足够新的 Oracle 版本中,您可以使用查询FETCH FIRST 1 ROW ONLY
来代替 ROWNUM
。我不认为这有什么不同。
推荐阅读
- microsoft-translator - Azure 翻译文本 - 排除检测到的错误语言
- excel - 出现错误,无法设置范围类的 formulaArray 属性
- wordpress - 自定义帖子类型和自定义重写规则的 Wordpress 分页问题
- random - 为什么 MersenneTwister 似乎为同一个种子生成不同的序列?
- php - 通过 API 调用在 Google 表格中创建下拉菜单
- javascript - 在没有 jquery 的情况下将 data-id 传递给引导模式
- acumatica - 恢复客户端数据库后无法编辑/打开自定义项
- c# - 使用 System.Runtime.Serialization.Json.DataContractJsonSerializer 反序列化具有接口属性类型的对象的最佳方法是什么?
- elassandra - 在 windows10 上运行 elassandra 发行版(不在 docker 上) ElasticSearch localhost:9200 无法访问
- javascript - 在 Vue.js 中,如何通过 vanilla js 更改 DOM 后恢复数据绑定?