有没有办法可以减少下面内部查询的OVER部分中'ORDER BY lro_pid'子句的影响?
SELECT *
FROM (SELECT a.*,
Row_Number() over (PARTITION BY search_point_type
ORDER BY lro_pid) spt_rank
FROM lro_search_point a
ORDER BY spt_rank)
WHERE spt_rank = 1;
我不关心在分区中订购此结果,因为我想完全按其他变量排序。 lro_pid是一个索引列,但这仍然像目前的资源一样浪费资源。 (也许有一种方法可以将排序限制在单行范围内?希望根本不会在分区内的排序上花费时间/精力)
答案 0 :(得分:5)
要尝试的几件事情:
你可以吗,例如OVER子句中的ORDER BY 'constant'
?
如果不允许按常数排序,ORDER BY (lro_pid * 0)
怎么样?
我不是Oracle专家(MSSQL更像是我的东西) - 因此有问题要回答你的问题!
答案 1 :(得分:4)
在分析ORDER BY中使用常量作为@Will建议似乎是最快的方法。 优化器仍然执行排序,但它比排序列更快。 此外,您可能希望删除第二个ORDER BY,或者至少将其移动到外部查询。
以下是我的测试用例:
--Create table, index, and dummy data.
create table lro_search_point(search_point_type number, lro_pid number, column1 number
,column2 number, column3 number);
create index lro_search_point_idx on lro_search_point(lro_pid);
insert /*+ append */ into lro_search_point
select mod(level, 10), level, level, level, level from dual connect by level <= 100000;
commit;
--Original version. Averages 0.53 seconds.
SELECT * FROM
(
SELECT a.*, Row_Number() over (PARTITION BY search_point_type ORDER BY lro_pid) spt_rank
FROM lro_search_point a
ORDER BY spt_rank
)
WHERE spt_rank=1;
--Sort by constant. Averages 0.33 seconds.
--This query and the one above have the same explain plan, basically it's
--SELECT/VIEW/SORT ORDER BY/WINDOW SORT PUSHED RANK/TABLE ACCESS FULL.
SELECT * FROM
(
SELECT a.*, Row_Number() over (PARTITION BY search_point_type ORDER BY -1) spt_rank
FROM lro_search_point a
ORDER BY spt_rank
)
WHERE spt_rank=1;
--Remove the ORDER BY (or at least move it to the outer query). Averages 0.27 seconds.
SELECT * FROM
(
SELECT a.*, Row_Number() over (PARTITION BY search_point_type ORDER BY -1) spt_rank
FROM lro_search_point a
)
WHERE spt_rank=1;
--Replace analytic with aggregate functions, averages 0.28 seconds.
--This idea is the whole reason I did this, but turns out it's no faster. *sigh*
--Plan is SELECT/SORT GROUP BY/TABLE ACCESS FULL.
--Note I'm using KEEP instead of just regular MIN.
--I assume that you want the values from the same row.
SELECT a.search_point_type
,min(lro_pid) keep (dense_rank first order by -1)
,min(column1) keep (dense_rank first order by -1)
,min(column2) keep (dense_rank first order by -1)
,min(column3) keep (dense_rank first order by -1)
FROM lro_search_point a
group by a.search_point_type;
答案 2 :(得分:-1)
要忽略条款ORDER BY
,您可以使用ORDER BY
rownum。