# 【Java开源数据库语言】基于SPL如何提高SQL优化效率

12 篇文章 27 订阅
29 篇文章 27 订阅

select a,b,sum(x) from T group by a,b where;
select c,d,max(y) from T group by c,d where;
select a,c,avg(y),min(z) from T group by a,c where;

from T --数据来自T表
select a,b,sum(x) group by a,b where--遍历中的第一种分组
select c,d,max(y) group by c,d where--遍历中的第二种分组
select a,c,avg(y),min(z) group by a,c where; --遍历中的第三种分组

create table T\_temp as select a,b,c,d,
sum(case whenthen x else 0 end) sumx,
max(case whenthen y else null end) maxy,
sum(case whenthen y else 0 end) sumy,
count(case whenthen 1 else null end) county,
min(case whenthen z else null end) minz
group by a,b,c,d;
select a,b,sum(sumx) from T\_temp group by a,b where;
select c,d,max(maxy) from T\_temp group by c,d where;
select a,c,sum(sumy)/sum(county),min(minz) from T\_temp group by a,c where;

TopN运算同样会遇到这种无奈。举个例子，用Oracle的SQL写top5大致是这样的：

select \* from (select x from T order by x desc) where rownum<=5

select top(x,5) from T

select \* from (select y,x,row\_number() over (partition by y order by x desc) rn from T) where rn<=5

select y,top(x,5) from T group by y

select o.oid,o.orderdate,o.amount
from orders o
left join city ci on o.cityid = ci.cityid
left join shipper sh on o.shid=sh.shid
left join employee e on o.eid=e.eid
left join supplier su on o.suid=su.suid
where ci.state='New York'
and e.title='manager'
and ...

SQL一般采用HASH JOIN算法实现这些关联，要计算 HASH 值并做比较。每次只能解析一个JOIN，有N个JOIN要执行N遍动作，每次关联后都需要保持中间结果供下一轮使用，计算过程复杂，数据也会被遍历多次，计算性能不好。

select o.oid,o.orderdate,o.amount
from orders o
left join city c on o.cid = c.# --订单表的城市编号通过序号#关联城市表
left join shipper sh on o.shid=sh.# --订单表运货商号通过序号#关联运货商表
left join employee e on o.eid=e.# --订单表的雇员编号通过序号#关联雇员表
left join supplier su on o.suid=su.#--订单表供应商号通过序号#关联供应商表
where ci.state='New York'
and e.title='manager'
and ...

select id,amt,tdate,from T
where id='10100'
and tdate>= to\_date('2021-01-10','yyyy-MM-dd')
and tdate<to_date('2021-01-25','yyyy-mm-dd')
and=""="" <p="">

create index index_T_1 on T(id)

• 一次遍历计算多种分组
AB
1=file(“T.ctx”).open().cursor(a,b,c,d,x,y,z
2cursor A1=A2.select(…).groups(a,b;sum(x))
3//定义遍历中的第一种过滤、分组
4cursor=A4.select(…).groups(c,d;max(y))
5//定义遍历中的第二种过滤、分组
6cursor=A6.select(…).groupx(a,c;avg(y),min(z))
7//定义遍历中的第三种过滤、分组
8//定义结束，开始计算三种方式的过滤、分组
• 用聚合的方式计算Top5

A
1=file(“T.ctx”).open()
2=A1.cursor@m(x).total(top(-5,x),top(5,x))
3//top(-5,x) 计算出 x 最大的前 5 名，top(5,x) 是 x 最小的前 5 名。

A
1=file(“T.ctx”).open()
2=A1.cursor@m(x,y).groups(y;top(-5,x),top(5,x))
• 用序号做关联的SPL代码：

A
1>env(city,file(“city.btx”).import@b()),env(employee,file(“employee.btx”).import@b()),…
2//系统初始化时，几个小表读入内存

A
1=file(“orders.ctx”).open().cursor(cid,eid,…).switch(cid,city:#;eid,employee:#;…)
2=A1.select(cid.state==“New York” && eid.title==“manager”…)
3//先序号关联，再引用关联表字段写过滤条件
• 高并发帐户查询的SPL代码：

AB
1=file(“T-original.ctx”).open().cursor(id,tdate,amt,…)
2=A1.sortx(id)=file(“T.ctx”)
3=B2.create@r(#id,tdate,amt,…).append@i(A2)
4=B2.open().index(index_id;id)
5//将原数据排序后，另存为新表，并为帐号建立索引

A
1=T.icursor(;id==10100 && tdate>=date(“2021-01-10”) && tdate<date(“2021-01-25”) && …,index_id).fetch()
2//查询代码非常简单

http://www.raqsoft.com.cn/wx/Query-run-batch-ad.html

## SPL资料

• 109
点赞
• 79
收藏
• 打赏
• 79
评论
04-08 781
11-18 167
11-07 1万+
07-20 7158
11-05 504
11-13 187
01-11 745
03-14 2228
02-13 1074

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。