我希望以下查询的一些指导。我们列出了实验列表以及它们当前的进度状态(为了简单起见,我已将状态缩减为4种,但我们的数据中有10种不同的状态)。我需要最终返回所有未完成实验的当前状态列表。选择最近的行,优化(Oracle SQL)
给定一个表exp_status,
Experiment | ID | Status
----------------------------
A | 1 | Starting
A | 2 | Working On It
B | 3 | Starting
B | 4 | Working On It
B | 5 | Finished Type I
C | 6 | Starting
D | 7 | Starting
D | 8 | Working On It
D | 9 | Finished Type II
E | 10 | Starting
E | 11 | Working On It
F | 12 | Starting
G | 13 | Starting
H | 14 | Starting
H | 15 | Working On It
H | 16 | Finished Type II
所需的结果集:
Experiment | ID | Status
----------------------------
A | 2 | Working On It
C | 6 | Starting
E | 11 | Working On It
F | 12 | Starting
G | 13 | Starting
最新的ID号将对应于最新状态。
现在,我在150秒内执行的当前代码。
SELECT *
FROM
(SELECT Experiment, ID, Status,
row_number() over (partition by Experiment
order by ID desc) as rn
FROM exp_status)
WHERE rn = 1
AND status NOT LIKE ('Finished%')
事情是,这段代码浪费了时间。结果集是从3.9百万张表中拉出的45,000行。这是因为大多数实验都处于完成状态。代码通过并命令所有这些代码只在最后过滤完成。表中大约95%的实验都处于完成阶段。我无法弄清楚如何使查询首先挑选出那个实验没有“成品”的所有实验和状态。我尝试了以下,但表现非常慢。
SELECT *
FROM exp_status
WHERE experiment NOT IN
(
SELECT experiment
FROM exp_status
WHERE status LIKE ('Finished%')
)
任何帮助将不胜感激!
如果status列被索引,那么可能值得使用'row_number()'函数将'status not like ...'条件移入内部select。 – 2012-07-12 11:47:26