标签: window-functions

Oracle中分页查询的速度

这对我来说是一个永无止境的话题,我想知道我是否会忽视某些事情.基本上我在应用程序中使用两种类型的SQL语句:

  1. 具有"后备"限制的常规查询
  2. 排序和分页查询

现在,我们正在谈论针对具有数百万条记录的表的一些查询,加入另外5个具有数百万条记录的表.显然,我们几乎不想获取所有这些,这就是为什么我们有上述两种方法来限制用户查询.

案例1非常简单.我们只添加一个额外的ROWNUM过滤器:

WHERE ...
  AND ROWNUM < ?
Run Code Online (Sandbox Code Playgroud)

这是非常快的,因为Oracle的CBO将考虑其执行计划考虑此过滤器,并可能应用一个FIRST_ROWS操作(类似于/*+FIRST_ROWS*/提示强制执行的操作).

然而,案例2对Oracle来说有点棘手,因为LIMIT ... OFFSET其他RDBMS中没有任何条款.因此,我们将"业务"查询嵌套在技术包装器中:

SELECT outer.* FROM (
  SELECT * FROM (
    SELECT inner.*, ROWNUM as RNUM, MAX(ROWNUM) OVER(PARTITION BY 1) as TOTAL_ROWS
    FROM (
      [... USER SORTED business query ...]
    ) inner
  ) 
  WHERE ROWNUM < ?
) outer
WHERE outer.RNUM > ?
Run Code Online (Sandbox Code Playgroud)

请注意,TOTAL_ROWS即使不获取所有数据,也会计算该字段以了解我们将拥有多少页.现在这个分页查询通常非常令人满意.但是时不时(正如我所说,在查询5M +记录时,可能包括非索引搜索),这运行2-3分钟.

编辑:请注意,潜在的瓶颈并不容易规避,因为在分页之前必须应用排序!

我想知道,这是最先进的模拟LIMIT ... OFFSET,包括TOTAL_ROWS在Oracle中,还是有更好的解决方案,设计会更快,例如使用ROW_NUMBER() …

sql performance oracle11g rownum window-functions

10
推荐指数
1
解决办法
4807
查看次数

Postgres会将WHERE子句下推到带有Window函数(Aggregate)的VIEW吗?

Pg's Window函数的文档:

窗口函数考虑的行是由查询的FROM子句生成的"虚拟表",由WHERE,GROUP BY和HAVING子句过滤,如果有的话.例如,任何窗口函数都看不到因为它不符合WHERE条件而被删除的行.查询可以包含多个窗口函数,这些函数通过不同的OVER子句以不同的方式对数据进行分片,但它们都作用于此虚拟表定义的相同行集合.

但是,我没有看到这一点.在我看来,选择过滤器非常靠近左边距和顶部(最后完成的事情).

=# EXPLAIN SELECT * FROM chrome_nvd.view_options where fkey_style = 303451;
                                                      QUERY PLAN                                                      
----------------------------------------------------------------------------------------------------------------------
 Subquery Scan view_options  (cost=2098450.26..2142926.28 rows=14825 width=180)
   Filter: (view_options.fkey_style = 303451)
   ->  Sort  (cost=2098450.26..2105862.93 rows=2965068 width=189)
         Sort Key: o.sequence
         ->  WindowAgg  (cost=1446776.02..1506077.38 rows=2965068 width=189)
               ->  Sort  (cost=1446776.02..1454188.69 rows=2965068 width=189)
                     Sort Key: h.name, k.name
                     ->  WindowAgg  (cost=802514.45..854403.14 rows=2965068 width=189)
                           ->  Sort  (cost=802514.45..809927.12 rows=2965068 width=189)
                                 Sort Key: h.name
                                 ->  Hash Join  (cost=18.52..210141.57 rows=2965068 width=189)
                                       Hash Cond: (o.fkey_opt_header = h.id)
                                       -> …
Run Code Online (Sandbox Code Playgroud)

postgresql where-clause window-functions

10
推荐指数
1
解决办法
2259
查看次数

PostgreSQL相当于TOP n WITH TIES:LIMIT"with ties"?

我在SQL Server中寻找类似的东西:

SELECT TOP n WITH TIES FROM tablename
Run Code Online (Sandbox Code Playgroud)

LIMIT在PostgreSQL中知道,但是上面存在的相同吗?我只是很好奇,因为它每次都会为我节省额外的查询.

如果我有一个Numbers属性表nums:{10, 9, 8, 8, 2}.我想做的事情如下:

SELECT nums FROM Numbers ORDER BY nums DESC LIMIT *with ties* 3
Run Code Online (Sandbox Code Playgroud)

它应该返回,{10, 9, 8, 8}因为它需要前3加上额外的,8因为它绑定另一个.

sql postgresql window-functions sql-limit

10
推荐指数
1
解决办法
9675
查看次数

GROUP BY由间隙分隔的连续日期

假设您(在Postgres 9.1中)有这样一个表:

date | value 
Run Code Online (Sandbox Code Playgroud)

它有一些空白(我的意思是:并非每个可能的日期在最小(日期)和最大(日期)之间有它的行).

我的问题是如何聚合这些数据,以便分别处理每个一致的组(没有间隙),如下所示:

min_date | max_date | [some aggregate of "value" column] 
Run Code Online (Sandbox Code Playgroud)

有什么想法怎么做?我相信这是可能的窗口功能,但是过了一段时间,试图lag()lead()我有点卡住了.

例如,如果数据是这样的:

 date          | value  
---------------+-------  
 2011-10-31    | 2  
 2011-11-01    | 8  
 2011-11-02    | 10  
 2012-09-13    | 1  
 2012-09-14    | 4  
 2012-09-15    | 5  
 2012-09-16    | 20  
 2012-10-30    | 10  
Run Code Online (Sandbox Code Playgroud)

输出(sum作为聚合)将是:

   min     |    max     |  sum  
-----------+------------+-------  
2011-10-31 | 2011-11-02 |  20  
2012-09-13 | 2012-09-16 |  30  
2012-10-30 | 2012-10-30 |  10  
Run Code Online (Sandbox Code Playgroud)

sql postgresql aggregate window-functions

10
推荐指数
1
解决办法
3713
查看次数

如何在没有分组的情况下制作SUM

这是我的问题..

Actual   Auction   Ammanat   id
7000     500       100       228,229
7000     100       100       228,229
7000     900       100       228,229
5000     0         0         230
Run Code Online (Sandbox Code Playgroud)

我想要下面给出的结果

Actual   Auction   Ammanat   Remaining  id
7000     500       100       5550       228,229
7000     100       100       5550       228,229
7000     900       100       5550       228,229
5000     0         0         5000        230
Run Code Online (Sandbox Code Playgroud)

在这里,Remaining(sum(auction)-actual).

我正在使用PostgreSQL.但是如果有人知道SQL Server中的解决方案,那就没问题了.

sql sql-server postgresql window-functions

10
推荐指数
2
解决办法
3万
查看次数

Spark和SparkSQL:如何模仿窗口功能?

描述

给定一个数据帧 df

id |       date
---------------
 1 | 2015-09-01
 2 | 2015-09-01
 1 | 2015-09-03
 1 | 2015-09-04
 2 | 2015-09-04
Run Code Online (Sandbox Code Playgroud)

我想创建一个运行计数器或索引,

  • 按相同的ID分组
  • 按该组中的日期排序,

从而

id |       date |  counter
--------------------------
 1 | 2015-09-01 |        1
 1 | 2015-09-03 |        2
 1 | 2015-09-04 |        3
 2 | 2015-09-01 |        1
 2 | 2015-09-04 |        2
Run Code Online (Sandbox Code Playgroud)

这是我可以通过窗口功能实现的,例如

val w = Window.partitionBy("id").orderBy("date")
val resultDF = df.select( df("id"), rowNumber().over(w) )
Run Code Online (Sandbox Code Playgroud)

不幸的是,Spark 1.4.1不支持常规数据帧的窗口函数:

org.apache.spark.sql.AnalysisException: Could not resolve window function 'row_number'. Note that, …
Run Code Online (Sandbox Code Playgroud)

scala window-functions apache-spark apache-spark-sql

10
推荐指数
2
解决办法
1万
查看次数

Spark任务不具有滞后窗口功能可序列化

我注意到,如果我使用函数调用map(),我在DataFrame上使用Window函数后,Spark会返回"Task not serializable"Exception这是我的代码:

val hc:org.apache.spark.sql.hive.HiveContext = new org.apache.spark.sql.hive.HiveContext(sc)
import hc.implicits._
import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions._
def f():String = "test"
case class P(name:String,surname:String)
val lag_result:org.apache.spark.sql.Column = lag($"name",1).over(Window.partitionBy($"surname"))
val lista:List[P] = List(P("N1","S1"),P("N2","S2"),P("N2","S2"))
val data_frame:org.apache.spark.sql.DataFrame = hc.createDataFrame(sc.parallelize(lista))
df.withColumn("lag_result", lag_result).map(x => f)
//df.withColumn("lag_result", lag_result).map{case x => def f():String = "test";f}.collect // This works
Run Code Online (Sandbox Code Playgroud)

这是堆栈跟踪:

org.apache.spark.SparkException:org.apache.spark.util.ClosureCleaner $ .ensureSerializable(ClosureCleaner.scala:304)org.apache.spark.util.ClosureCleaner $ .org $ apache $ spark $ util中无法序列化的任务$ ClosureCleaner $$ clean(ClosureCleaner.scala:294)atg.apache.spark.util.ClosureCleaner $ .clean(ClosureCleaner.scala:122)at org.apache.spark.SparkContext.clean(SparkContext.scala:2055)at at org.apache.spark.rdd.RDD $$ anonfun $ map $ 1.apply(RDD.scala:324)at org.apache.spark.rdd.RDD $$ anonfun $ map $ …

serialization scala window-functions apache-spark apache-spark-sql

10
推荐指数
1
解决办法
2760
查看次数

使用和不使用ORDER BY子句对分区进行分析计数

我不明白为什么ORDER BY在分析COUNT函数中使用子句时会有不同的结果.

使用一个简单的例子:

with req as
 (select 1 as n, 'A' as cls
    from dual
  union
  select 2 as n, 'A' as cls
    from dual)
select req.*, count(*) over(partition by cls) as cnt from req;
Run Code Online (Sandbox Code Playgroud)

给出以下结果:

N   CLS CNT
2   A   2
1   A   2
Run Code Online (Sandbox Code Playgroud)

然而,当ORDER BY在分析子句中添加一个时,结果是不同的!

with req as
 (select 1 as n, 'A' as cls
    from dual
  union
  select 2 as n, 'A' as cls
    from dual)
select req.*, count(*) over(partition by …
Run Code Online (Sandbox Code Playgroud)

sql oracle window-functions

10
推荐指数
2
解决办法
2451
查看次数

SQLServer count()over()with distinct

我正在研究一个项目,我们需要计算不同行的数量.方案的简化版本包括user表,keyword表和keyword_user表.

user表仅包括公共用户元数据,如名称等.下面列出了其他表.

keyword_user:

id
user_id
keyword_id
Run Code Online (Sandbox Code Playgroud)


关键词:

id,
description
Run Code Online (Sandbox Code Playgroud)

我想要做的是根据用户keyword_id找到最大用户数(5),同时还计算匹配行的总数.计数必须是不同的.

查询:

SELECT TOP 5 u.[id], 
             u.[firstname], 
             u.[lastname], 
             total = Count(*) OVER() 
FROM   [user] u 
       INNER JOIN [keyword_user] ku 
               ON u.[id] = ku.[user_id] 
WHERE  ( ku.keyword_id IN ( '5f6501ec-0a71-4067-a21d-3c5f87a76411', 'c19b95c0-8554-4bbd-9526-db8f1c4f1edf')) 
       AND u.id NOT IN ( '12db3001-b3b9-4626-8a02-2519102cb53a' ) 
Run Code Online (Sandbox Code Playgroud)

结果集:

+--------------------------------------+-----------+----------+-------+
|                  id                  | firstname | lastname | total |
+--------------------------------------+-----------+----------+-------+
| F0527AC3-747A-45A6-9CF9-B1F6C7F548F8 | Kasper    | Thomsen  |     3 |
| 95988F6D-9C91-4779-B6C3-3D4B4D6AE836 | Michael   | …
Run Code Online (Sandbox Code Playgroud)

sql-server join inner-join count window-functions

9
推荐指数
1
解决办法
483
查看次数

使用ROW_NUMBER和PARTITION BY获取第一行和最后一行

样本输入

Name | Value | Timestamp
-----|-------|-----------------
One  | 1     | 2016-01-01 02:00
Two  | 3     | 2016-01-01 03:00
One  | 2     | 2016-01-02 02:00
Two  | 4     | 2016-01-03 04:00
Run Code Online (Sandbox Code Playgroud)

期望的输出

Name | Value | EarliestTimestamp | LatestTimestamp
-----|-------|-------------------|-----------------
One  | 2     | 2016-01-01 02:00  | 2016-01-02 02:00
Two  | 4     | 2016-01-01 03:00  | 2016-01-03 04:00
Run Code Online (Sandbox Code Playgroud)

尝试查询

我想使用ROW_NUMBER()PARTITION BY获得最新的Name,Value但我也想要最早和最新的Timestamp价值:

SELECT
    t.Name,
    t.Value,
    t.????????? AS EarliestTimestamp,
    t.Timestamp AS LatestTimestamp …
Run Code Online (Sandbox Code Playgroud)

sql t-sql sql-server row-number window-functions

9
推荐指数
1
解决办法
2万
查看次数