关于 Oracle 性能(Multi-SELECT + Single COUNT() 与 Single-SELECT + Multi COUNT() )
About Oracle performance (Multi-SELECT + Single COUNT() vs Single-SELECT + Multi COUNT() )
哪种方式(仅速度)更好?
- 单个 SELECT(多个 COUNT(),多个 TO_CHAR())
SELECT
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') RG_DATE, COUNT(T.UUID) VISITS
FROM
ACCOUNT T
GROUP BY
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD')
HAVING
COUNT(T.UUID) > 0
EDIT
SELECT
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') RG_DATE, COUNT(T.UUID) VISITS
FROM
ACCOUNT T
GROUP BY
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD')
HAVING
COUNT(T.UUID) > 0
AND COUNT(T.UUID) >= 2 -- Spring mybatis generated code
AND COUNT(T.UUID) < 5 -- Spring mybatis generated code
- 双 SELECT(单 COUNT(),多 TO_CHAR())
SELECT
T.UUID, T.RG_DATE, T.VISITS
FROM (
SELECT
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') RG_DATE, COUNT(T.UUID) VISITS
FROM
ACCOUNT T
GROUP BY
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD')
) T
WHERE
T.VISITS > 0
- 多个SELECT(单个COUNT(),单个TO_CHAR())
SELECT
T.UUID, T.RG_DATE, T.VISITS
FROM (
SELECT
T.UUID, T.RG_DATE, COUNT(T.UUID) VISITS
FROM (
SELECT
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') RG_DATE
FROM
ACCOUNT T
) T
GROUP BY
T.UUID, T.RG_DATE
) T
WHERE
T.VISITS > 0
我已经在小数据库中测试过了,差异很小,所以我无法决定哪个是最好的。
大(也许是巨型)数据库怎么样?
Oracle 优化器会将第 3 个查询转换为等于第 2 个(子查询视图合并转换),因此默认情况下它们将具有相同的计划。
第一个更好:having
将作为 group-by
操作的过滤器执行。如果您比较执行计划,您会发现差异。
我建议使用 trunc(rg_date)
而不是 to_char 和适当的 nls_date_format。
哪种方式(仅速度)更好?
- 单个 SELECT(多个 COUNT(),多个 TO_CHAR())
SELECT
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') RG_DATE, COUNT(T.UUID) VISITS
FROM
ACCOUNT T
GROUP BY
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD')
HAVING
COUNT(T.UUID) > 0
EDIT
SELECT T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') RG_DATE, COUNT(T.UUID) VISITS FROM ACCOUNT T GROUP BY T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') HAVING COUNT(T.UUID) > 0 AND COUNT(T.UUID) >= 2 -- Spring mybatis generated code AND COUNT(T.UUID) < 5 -- Spring mybatis generated code
- 双 SELECT(单 COUNT(),多 TO_CHAR())
SELECT
T.UUID, T.RG_DATE, T.VISITS
FROM (
SELECT
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') RG_DATE, COUNT(T.UUID) VISITS
FROM
ACCOUNT T
GROUP BY
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD')
) T
WHERE
T.VISITS > 0
- 多个SELECT(单个COUNT(),单个TO_CHAR())
SELECT
T.UUID, T.RG_DATE, T.VISITS
FROM (
SELECT
T.UUID, T.RG_DATE, COUNT(T.UUID) VISITS
FROM (
SELECT
T.UUID, TO_CHAR(T.RG_DATE, 'YYYY-MM-DD') RG_DATE
FROM
ACCOUNT T
) T
GROUP BY
T.UUID, T.RG_DATE
) T
WHERE
T.VISITS > 0
我已经在小数据库中测试过了,差异很小,所以我无法决定哪个是最好的。 大(也许是巨型)数据库怎么样?
Oracle 优化器会将第 3 个查询转换为等于第 2 个(子查询视图合并转换),因此默认情况下它们将具有相同的计划。
第一个更好:having
将作为 group-by
操作的过滤器执行。如果您比较执行计划,您会发现差异。
我建议使用 trunc(rg_date)
而不是 to_char 和适当的 nls_date_format。