1、 技术背景
1.1 背景技术
在分布式mysql中间件系统,DML语句中,子查询需要可能涉及到多个数据分片,如果在DML语句使用子查询,需要首先解析出子查询的具体内容,然后根据路由把子查询发往到各个分片并收集查询结果,才能在上一级查询中进行下一步的查询。
已有的实现中均没有很好的不受限制的支持子查询,即使有支持也仅限于子查询所在的表与父查询所在的表路由和分片方式一致,而该实现对sql语句要求特别高,可操作性不强。
1.2 现有技术
目前并没有分布式mysql中间件系统中能完整的执行带子查询的sql处理。
2、技术方案
2.1 所要解决的技术问题
在分布式mysql中间件系统中,完整的支持带子查询的sql请求
2.2 技术方案
本方案主要有4个步骤,其中步骤1),2),3)是不断迭代执行的。
1)首先解析出完整的sql语句中的子查询以及子查询与父查询的交互方式
2)优先执行子查询
3)汇总子查询的查询结果,根据子查询与父查询的交互方式,重新拼装sql,然后去执行父查询
4)不断迭代执行,直到sql被执行完毕
举例
SELECT [FirstName]
,[MiddleName]
,[LastName]
FROM [AdventureWorks].[Person].[Contact]
WHERE ContactID IN
(SELECT EmployeeID
FROM [AdventureWorks].[HumanResources].[Employee]
WHERE SickLeaveHours>68)
对于这种查询语句,处理的过程如下
1)首先通过sql解析,解析出子查询
SELECT EmployeeID
FROM [AdventureWorks].[HumanResources].[Employee]
WHERE SickLeaveHours>68
2)执行子查询,子查询的执行也会涉及到数据的路由,可能会发送到若干数据分片去执行。
SELECT EmployeeID
FROM [AdventureWorks].[HumanResources].[Employee]
WHERE SickLeaveHours>68
3)上一条子查询结果返回后,与父查询的WHERE 关键词进行再次拼装和处理,例如,若该子查询返回的是 ID数据为(1,3,89),则该结果重新与父查询进行sql拼装组合为
SELECT [FirstName]
,[MiddleName]
,[LastName]
FROM [AdventureWorks].[Person].[Contact]
WHERE ContactID IN (1,23,89)
4)将该查询发到相应的数据分片上去执行,再次取得的结果为最终结果。
2.3流程图
图2-1
图2-2
图2-2中的“不带子查询的SQL处理”对应于图2-1的流程。
2.3 有益效果
通过本技术方案,可以让分布式mysql中间件系统能够保持分布式系统的优点的前提下,尽可能的处理复杂的带子查询的sql语句,并且能够支持OLAP的应用。
2.4 键点
1)在分布式mysql中间件系统中,通过sql子查询与父查询的解析关系,能够将sql子查询的结果与父查询重新拼装成新的迭代后的sql查询,从而使整个系统能够处理复杂的带子查询的sql处理。
2.5 名词解释
分布式mysql中间件系统: 类似于mysql官方提供的mysql proxy架构的系统,能够屏蔽数据库系统底层数据分布和处理,能够并行执行sql处理并进行结果汇总。
sql解析:将sql语句中各种语法元素,比如关键词select,from,where, in, any等内部各种信息解析的处理。