Chinaunix首页 | 论坛 | 博客
  • 博客访问: 425884
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 518
  • 用 户 组: 普通用户
  • 注册时间: 2015-12-14 12:10
个人简介

邮箱:oxwangfeng@qq.com

文章分类

全部博文(43)

文章存档

2021年(1)

2018年(7)

2017年(9)

2016年(26)

我的朋友

分类: 服务器与存储

2016-01-28 14:00:37

一些多机查询计算场景下,要求合并多机数据源,假设某个需求需要将数据再次计算,而计算的列不在select查询中,拿回来的多机数据源因为没有需要计算的列,就无法计算;

通过记录原来select的列数,将需要再次计算的列附加到select列中,待计算完毕后,按照原来的select列数将数据发送给客户端。

本方案应用于多机查询处理中(分布式数据库),结合数据定义配置,使用本方法能够获取到查询需要的额外列是否真实有效,结合数据散列方法优化本方法的使用。

处理流程如下图所示:


上图的处理流程解释:

Original query:原始查询,一般是用户发给数据库的查询语句;

Sytax tree:语法树,用户发送给数据库的查询语句,通过解析器生成的一个可供代码处理的逻辑结构;

Fetch select list:这个动作是获取SELECT查询语句中的查询列。

Have group:这个动作是检查SELECT查询语句中是否存在GROUP关键字。

Have order:这个动作是检查SELECT查询语句中是否存在ORDER关键字。

Select list:一个存储SELECT语句中查询列的数据结构。

Select list, [group list, order list]:修改后的查询语句格式,括弧里面的新增列,是附加到原始列后面的。

处理流程步骤:

1.       原始SQL解析成语法树结构,该语法树能够提供一个代码结构,后续处理流程会使用到这个代码结构。

2.       首先扫描SELECT查询的列,将SELECT的列存储到SELECT LIST结构中。

3.       扫描语法树查看是否有GROUP(分组)关键字存在,如果存在,需要判断GROUP分组的列在SELECT LIST中是否已经存在,如果不存在,则将GROUP分组列增加到SELECT LIST中,并将GROUP分组列附加到原查询语句的查询列尾部,并且记录下分组列在查询列中的位置。

4.       扫描语法树查看是否有ORDER(排序)关键字存在,如果存在,需要判断SELECT LIST是否已经存在ORDER排序列,如果ORDER排序列没有包含在SELECT LIST中,则将ORDER排序列放入SELECT LIST中,并且将ORDER排序列附加到查询语句尾部,标记ORDER排序列在查询语句中的位置。


经过处理流程1234就将客户端发送给数据库的原始查询语句改写为新的查询语句,下面使用一个具体例子来说明实际处理过程。


例:

Original query(原始查询语句,客户端发送给数据库的查询语句):SELECT email FROM userInfo WHERE create_time > ‘2011-11-11’ GROUP BY name order by id desc;

syntax tree:SQL解析后的语法树(略,这是其他独立模块提供的)

    Fetch select list:扫描语法树,可以发现SELECT查询的列有email,因此,将email存放到SELECT LIST

    Have group:扫描语法树,发现有GROUP关键字,分组列name不存在与SELECT LIST中,因将name放入SELECT LIST中,并且将name附加到查询列后面,这时候SQL语句为SELECT email, name FROM…,标记分组列name在查询中的位置为1(从左到右,从0开始,email位置为0name1)。

    Have order:扫描语法树,发现有ORDER关键字,排序列为id,该列不在SELECT LIST中,因此将排序列ID附加到查询语句中,查询语句变为SELECT email, name, id FROM … ,标记排序列在查询中的位置为2

经过一系列处理流程,那么为了实现这次查询,已经将查询重写改写为形成一个新的查询:

SELECT email,name, id FROM userInfo WHERE create_time > ‘2011-11-11’ GROUP BY name ORDER BY id DESC;

    所得到的信息有:原始查询的列数,改写后的列数,分组列位置,排序列的位置。

    使用处理后的SQL语句从数据存放点取回数据,根据所得到的信息,依次执行分组,排序,然后再发送的时候,按照原始查询的列数发送数据到客户端。



分库分表后能够支持复杂查询,如GROUP、ORDER等等;数据存储节点参与计算,相比直接把数据全部查询到应用程序中进行计算,具有更小的网络开销,更快的计算速度。
在多机查询中,不需要应用程序参与查询计算;通过关系代数等价变化的方式,重写查询语句,让数据节点参与查询计算的方式,相比常规方案性价比要高。 



阅读(4843) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~