当前位置: 首页 > news >正文

服装行业网站开发/百度搜索风云榜排行榜

服装行业网站开发,百度搜索风云榜排行榜,织梦网站在css中怎样做导航栏,怎么做网站导航条接下来几篇文章将分析一些热门数据库中的窗口函数实现方式,主要包括 节点间并发、节点内并发、具体实现、内存控制,以及其它值得注意的细节。 TiDB 代码:代码 文档:文档 design doc: design doc 窗口函数分组 在 parser 将 sq…

接下来几篇文章将分析一些热门数据库中的窗口函数实现方式,主要包括 节点间并发、节点内并发、具体实现、内存控制,以及其它值得注意的细节。

TiDB

代码:代码
文档:文档
design doc: design doc

窗口函数分组

在 parser 将 sql 解析为 ast 之后,tidb 的 planbuilder 会将 windowFunction 进行分组,合并具有相同 spec name 的窗口,核心逻辑在以下函数中:

func (b *PlanBuilder) groupWindowFuncs(windowFuncs []*ast.WindowFuncExpr) (map[*ast.WindowSpec][]*ast.WindowFuncExpr, []*ast.WindowSpec, error) {// updatedSpecMap is used to handle the specifications that have frame clause changed.updatedSpecMap := make(map[string][]*ast.WindowSpec)groupedWindow := make(map[*ast.WindowSpec][]*ast.WindowFuncExpr)orderedSpec := make([]*ast.WindowSpec, 0, len(windowFuncs))for _, windowFunc := range windowFuncs {if windowFunc.Spec.Name.L == "" {spec := &windowFunc.Specif spec.Ref.L != "" {ref, ok := b.windowSpecs[spec.Ref.L]if !ok {return nil, nil, ErrWindowNoSuchWindow.GenWithStackByArgs(getWindowName(spec.Ref.O))}err := mergeWindowSpec(spec, ref)if err != nil {return nil, nil, err}}spec, _ = b.handleDefaultFrame(spec, windowFunc.F)groupedWindow[spec] = append(groupedWindow[spec], windowFunc)orderedSpec = appendIfAbsentWindowSpec(orderedSpec, spec)continue}name := windowFunc.Spec.Name.Lspec, ok := b.windowSpecs[name]if !ok {return nil, nil, ErrWindowNoSuchWindow.GenWithStackByArgs(windowFunc.Spec.Name.O)}newSpec, updated := b.handleDefaultFrame(spec, windowFunc.F)if !updated {groupedWindow[spec] = append(groupedWindow[spec], windowFunc)orderedSpec = appendIfAbsentWindowSpec(orderedSpec, spec)} else {var updatedSpec *ast.WindowSpecif _, ok := updatedSpecMap[name]; !ok {updatedSpecMap[name] = []*ast.WindowSpec{newSpec}updatedSpec = newSpec} else {for _, spec := range updatedSpecMap[name] {eq, err := specEqual(spec, newSpec)if err != nil {return nil, nil, err}if eq {updatedSpec = specbreak}}if updatedSpec == nil {updatedSpec = newSpecupdatedSpecMap[name] = append(updatedSpecMap[name], newSpec)}}groupedWindow[updatedSpec] = append(groupedWindow[updatedSpec], windowFunc)orderedSpec = appendIfAbsentWindowSpec(orderedSpec, updatedSpec)}}// Unused window specs should also be checked in b.buildWindowFunctions,// so we add them to `groupedWindow` with empty window functions.for _, spec := range b.windowSpecs {if _, ok := groupedWindow[spec]; !ok {if _, ok = updatedSpecMap[spec.Name.L]; !ok {groupedWindow[spec] = nilorderedSpec = appendIfAbsentWindowSpec(orderedSpec, spec)}}}return groupedWindow, orderedSpec, nil

这个函数有两个返回值,第一个是 spec 到 func 的 map,第二个是 spec 的切片,函数流程如下:

依次遍历所有 windowFunction:

  1. 如果 spec 匿名:
    • 首先调用 mergeWindowSpec 处理 ref spec(形如 w2 as w1 order by deptid),填充 partitionBy 和 orderBy
    • 调用 handleDefaultFrame 函数处理 frame,会根据 func 的默认 frame 与 spec frame 进行组合。
    • 将这对 spec/func 添加到返回值中
    • continue
  2. 对于具名 spec:
    • 首先处理 frame,注意对于相同的 spec,不同的 func 可能会产生不同的 frame,从而改变 spec。
    • 如果 spec 不会因 frame 改变,添加到返回值中,返回。
  3. 否则,利用 specEqual 函数判断是否之前已经生成出来过相同的 spec。如果有就合并,如果没有就创建。
    然后添加到返回值中,返回。

想到一个优化点:为什么不用 specEqual 判断匿名 spec 和具名 spec 是否相等从而进行更多的合并。。联系了开发者,称最后没来得及做,所以留了个 todo。

一个问题:
在 tidb 中,在同一个窗口 w 上执行 row_number 和 rank,并不会将它们分到一个组中。

mysql> explain select *, row_number() over w, rank() over w from employee window w as (partition by deptid);
+--------------------------------+---------+-----------+----------------+---------------------------------------------------------------------------------------------------------+
| id                             | estRows | task      | access object  | operator info                                                                                           |
+--------------------------------+---------+-----------+----------------+---------------------------------------------------------------------------------------------------------+
| Projection_8                   | 17.00   | root      |                | test.employee.empid, test.employee.deptid, test.employee.salary, Column#8, Column#7                     |
| └─Window_10                    | 17.00   | root      |                | row_number()->Column#8 over(partition by test.employee.deptid rows between current row and current row) |
|   └─Window_11                  | 17.00   | root      |                | rank()->Column#7 over(partition by test.employee.deptid)                                                |
|     └─Sort_15                  | 17.00   | root      |                | test.employee.deptid                                                                                    |
|       └─TableReader_14         | 17.00   | root      |                | data:TableFullScan_13                                                                                   |
|         └─TableFullScan_13     | 17.00   | cop[tikv] | table:employee | keep order:false, stats:pseudo                                                                          |
+--------------------------------+---------+-----------+----------------+---------------------------------------------------------------------------------------------------------+

答案:因为 handleDefaultFrame 会分别对这两个函数进行处理:

  1. 给 row_number 加了一个 deafult frame(between current row and current row),rank 没加,所以不认为他们是一组了。

至于为什么要给 row_number 加 default_frame,开发者的回复是,为了避免将整个分区物化的内存消耗,所以给 row_number 加了一个宽度为 1 的窗口。

http://www.jmfq.cn/news/4841713.html

相关文章:

  • 上海网站建设 乐云seo/官网百度
  • 局域网内做网站/百度热线
  • 网站备案ip查询系统/企业产品推广策划方案
  • 怎么黑进网站后台/宁波seo公司推荐
  • 网上做兼职做网站/站长工具推荐
  • 洛阳bbs/优化软件seo排名
  • 成都市建设网扬尘监控网站/竞价推广方案
  • 网站建设必须注意的事项/营销网站案例
  • 网站制作营销型/株洲百度seo
  • 网站支付界面怎么做/中文搜索引擎大全
  • 怎样购买起名软件自己做网站/山东济南最新消息
  • 小程序云开发教程/百度seo排名推广
  • 宜宾建设网站/网络营销的含义特点
  • 做母婴网站/seo优化公司
  • 手机网站建设流程 知乎/拉新推广怎么快速拉人
  • 108社区找工作/seo咨询岳阳
  • 福建建设人才网/黄冈seo顾问
  • 做网站公司排名/营销网站建设方案
  • 比较简洁大方的网站/做网站推广的公司
  • 建设网站论坛/上海百度seo网站优化
  • 别人帮自己做网站有后门吗/网站结构优化
  • 官方网站下载官方版本/排名前50名免费的网站
  • 做网站要要多少钱/关键字挖掘爱站网
  • 做初中物理题目的网站/推广一次多少钱
  • vip电影网站建设/网站百度权重
  • 泉州建设部网站/周口网络推广哪家好
  • b2b网站怎么做关键词优化/广东今日最新疫情通报
  • 营销平台建设/湛江seo网站管理
  • 网站建设专业可行性分析/开发制作app软件
  • 网站建设摊销时间是多久/推广普通话手抄报简单又好看