Sql Oracle 12c—加入最大日期记录的有效方法
对于给定的Sql Oracle 12c—加入最大日期记录的有效方法,sql,oracle,join,oracle12c,Sql,Oracle,Join,Oracle12c,对于给定的employee_ID,我有以下将表连接到最新记录的方法,我想知道是否有更有效/更快的方法来检索最新记录,最好的方法是什么 SELECT * FROM EMPLOYEE WHERE NOT EXISTS ( SELECT 1 FROM EMPLOYEE D JOIN EMPLOYEE_HISTORY E
employee_ID
,我有以下将表连接到最新记录的方法,我想知道是否有更有效/更快的方法来检索最新记录,最好的方法是什么
SELECT * FROM EMPLOYEE
WHERE NOT EXISTS (
SELECT 1
FROM EMPLOYEE D
JOIN EMPLOYEE_HISTORY E
ON E.EMPLOYEE_ID = D.EMPLOYEE_ID
AND E.CREATE_DATE IN (SELECT MAX(CREATE_DATE)
FROM EMPLOYEE_HISTORY
WHERE EMPLOYEE_ID = D.EMPLOYEE_ID)
)
当我将explain计划与下面的查询进行比较时,下面的方法似乎成本更高
SELECT *
FROM EMPLOYEE
WHERE NOT EXISTS
(SELECT 1
FROM EMPLOYEE D
JOIN (
SELECT E.*
FROM EMPLOYEE_HISTORY E
INNER JOIN (
SELECT EMPLOYEE_ID
, MAX(CREATE_DATE) max_date
FROM EMPLOYEE_HISTORY E2
GROUP BY EMPLOYEE_ID
) EE
ON EE.EMPLOYEE_ID = E.EMPLOYEE_ID
AND EE.max_date = E.CREATE_DATE
) A
ON A.EMPLOYEE_ID = D.EMPLOYEE_ID
AND ROWNUM = 1)
那么这是否意味着它确实更好
创建日期没有索引,但是主键在员工ID上,如果员工的创建日期必须在员工ID历史记录中的最大创建日期之后,则创建日期 那么对于该员工ID,在员工历史记录中不存在相等或更高的创建日期
SELECT *
FROM EMPLOYEE Emp
WHERE NOT EXISTS (
SELECT 1
FROM EMPLOYEE_HISTORY Hist
WHERE Hist.EMPLOYEE_ID = Emp.EMPLOYEE_ID
AND Hist.CREATE_DATE >= Emp.CREATE_DATE
)
测试员工的创建日期是否必须在员工历史记录中该员工ID的最大创建日期之后 那么对于该员工ID,在员工历史记录中不存在相等或更高的创建日期
SELECT *
FROM EMPLOYEE Emp
WHERE NOT EXISTS (
SELECT 1
FROM EMPLOYEE_HISTORY Hist
WHERE Hist.EMPLOYEE_ID = Emp.EMPLOYEE_ID
AND Hist.CREATE_DATE >= Emp.CREATE_DATE
)
Test我将使用
=
而不是中的编写查询:
SELECT 1
FROM EMPLOYEE E JOIN
EMPLOYEE_HISTORY EH
ON EH.EMPLOYEE_ID = E.EMPLOYEE_ID AND
EH.CREATE_DATE = (SELECT MAX(EH2.CREATE_DATE)
FROM EMPLOYEE_HISTORY EH2
WHERE EH2.EMPLOYEE_ID = EH.EMPLOYEE_ID
);
对于比较而言,
中的比=
更一般
您的主键索引应该用于子查询,这将使它非常快
假设您确实希望返回实际的列,那么我不确定是否有方法可以更快地返回
如果您确实只选择了1
,那么请忘记最近的记录,只使用存在的记录即可:
SELECT 1
FROM EMPLOYEE E
WHERE EXISTS (SELECT 1
FROM EMPLOYEE_HISTORY EH2
WHERE EH2.EMPLOYEE_ID = E.EMPLOYEE_ID
);
您的查询检查的唯一附加条件是CREATE\u DATE
不为空,但我猜这始终是真的。我将使用=
而不是中的编写查询:
SELECT 1
FROM EMPLOYEE E JOIN
EMPLOYEE_HISTORY EH
ON EH.EMPLOYEE_ID = E.EMPLOYEE_ID AND
EH.CREATE_DATE = (SELECT MAX(EH2.CREATE_DATE)
FROM EMPLOYEE_HISTORY EH2
WHERE EH2.EMPLOYEE_ID = EH.EMPLOYEE_ID
);
对于比较而言,
中的比=
更一般
您的主键索引应该用于子查询,这将使它非常快
假设您确实希望返回实际的列,那么我不确定是否有方法可以更快地返回
如果您确实只选择了1
,那么请忘记最近的记录,只使用存在的记录即可:
SELECT 1
FROM EMPLOYEE E
WHERE EXISTS (SELECT 1
FROM EMPLOYEE_HISTORY EH2
WHERE EH2.EMPLOYEE_ID = E.EMPLOYEE_ID
);
您的查询检查的唯一附加条件是CREATE\u DATE
不为空,但我猜这始终是真的。使用RANK
(或densite\u RANK
或ROW\u NUMBER
)分析函数:
SELECT 1
FROM EMPLOYEE E
JOIN (
SELECT *
FROM (
SELECT H.*,
RANK() OVER ( PARTITION BY EMPLOYEE_ID ORDER BY CREATE_DATE DESC ) AS rnk
FROM EMPLOYEE_HISTORY H
)
WHERE rnk = 1
) H
ON H.EMPLOYEE_ID = E.EMPLOYEE_ID
使用排名
(或密集排名
或行数
)分析功能:
SELECT 1
FROM EMPLOYEE E
JOIN (
SELECT *
FROM (
SELECT H.*,
RANK() OVER ( PARTITION BY EMPLOYEE_ID ORDER BY CREATE_DATE DESC ) AS rnk
FROM EMPLOYEE_HISTORY H
)
WHERE rnk = 1
) H
ON H.EMPLOYEE_ID = E.EMPLOYEE_ID
您能显示完整的查询吗?
中不需要。子查询不会返回多行<代码>=
可以使用。(但这很可能对性能没有影响。)@VamsiPrabhala请参见编辑。相反,在中,使用密集等级分析功能过滤员工历史记录中的记录,然后(在更高级别上)进行连接。您可以尝试在员工历史记录(员工id ASC,创建日期描述)上建立索引
如果create\u date
尚未在其他索引中按降序排列。是否可以显示完整的查询?不需要在那里设置。子查询不会返回多行<代码>=
可以使用。(但这很可能对性能没有影响。)@VamsiPrabhala请参见编辑。相反,在中,使用密集等级分析功能过滤员工历史记录中的记录,然后(在更高级别上)进行连接。您可以尝试在员工历史记录(员工id ASC,创建日期描述)上建立索引
ifcreate\u date
尚未在其他索引中按降序排列。这是迄今为止成本最低的方法。排号非常昂贵。谢谢这是迄今为止成本最低的方法。排号非常昂贵。谢谢