查询优化(解析函数)

时间:2017-10-06 23:54:27

标签: sql oracle query-optimization

我有一张巨大的卖桌。 在此表中,我们有产品和销售日期。 我想为每个产品找到最近的5个销售。 它很容易找到查询,但我想找到一个快速的? 例如:

    with foo as
 (select RANK() OVER(PARTITION BY product ORDER BY sale_date DESC) RK, p.*
    from sell p)
select * from foo where rk < 6

但是这个查询会进行全表扫描并对每一行进行排序。 所以它不是一个有效的查询。

有什么想做的更好吗?

非常感谢

2 个答案:

答案 0 :(得分:1)

此查询:

with foo as (
      select RANK() OVER (PARTITION BY product ORDER BY sale_date DESC) as RK,
             p.*
      from sell p
     )
select *
from foo
where rk < 6;

可以利用sell(product, sale_date)上的索引。

答案 1 :(得分:0)

您必须在某个时刻扫描整个表格以满足功能要求:

  

我想为每种产品找到最后一次销售。

你不会找到一种更有效的方法,使用窗口函数如RANK()但严格来说我会使用ROW_NUMBER()来满足该要求,因为RANK()或{{1}可以重复值(因此您可能会在产品上获得超过5行)。

如果您可以按日期限制子查询的范围,例如忽略超过6个月的所有销售,然后您可能会避免表扫描。但根据您对需求的描述,这似乎并不适用。请注意,如果查询优化器认为您需要表的大部分而不值得使用索引,则可以选择表扫描。

DENSE_RANK()

我避免使用“化妆品CTE”( CTE用作替代派生表子查询)。