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

利用DeepSeek改写递归CTE SQL语句为Python程序及优化

前文有一个高效的sql,好奇能否把它改写成python程序,让DeepSeek改写,告诉他:
把如下sql精确翻译成python,用列表代替表,注意这是递归CTE。

with n as (
select level n from dual connect by level<=5
)
,A as (select n1.n x, n2.n y, power(2,rownum-1) bit from n n1,n n2)
,C as (
select a1.bit,a1.x,a1.y,sum(a2.bit) bit2from a a1,a a2
where (a1.x-a2.x)*(a1.y-a2.y)<=0
group by a1.bit,a1.x,a1.y
)
,b(cnt,bit,bit2) as (
select 1,c.bit,c.bit2from c
union all
select b.cnt+1,b.bit+c.bit,bitand(b.bit2,c.bit2)
from b,c
where c.bit>b.bit and bitand(b.bit2,c.bit)>0
)
select listagg('('||a.x||','||a.y||')') within group(order by r.bit) 
from (select * from (select b.*,rank() over(order by cnt desc) rnk from b)where rnk=1) r join a on bitand(r.bit,a.bit)>0
group by r.bit;

他翻译的结果如下:

def main():# with n as (select level n from dual connect by level<=5)n_list = [i for i in range(1, 6)]  # level从1开始# A as (select n1.n x, n2.n y, power(2,rownum-1) bit from n n1,n n2)A = []bit_value = 1for x in n_list:for y in n_list:A.append({'x': x, 'y': y, 'bit': bit_value})bit_value *= 2# C as (select a1.bit,a1.x,a1.y, sum(a2.bit) bit2 from a a1,a a2 where (a1.x-a2.x)*(a1.y-a2.y)<=0 group by a1.bit,a1.x,a1.y)C = []for a1 in A:bit2_sum = 0for a2 in A:if (a1['x'] - a2['x']) * (a1['y'] - a2['y']) <= 0:bit2_sum += a2['bit']C.append({'bit': a1['bit'],'x': a1['x'],'y': a1['y'],'bit2': bit2_sum})# 递归CTE b(cnt,bit,bit2)b = []# 初始部分: select 1,c.bit,c.bit2 from cfor c_row in C:b.append({'cnt': 1,'bit': c_row['bit'],'bit2': c_row['bit2']})# 递归部分: 模拟递归CTEchanged = Truewhile changed:changed = Falsenew_rows = []for b_row in b:for c_row in C:# where c.bit > b.bit and bitand(b.bit2, c.bit) > 0if (c_row['bit'] > b_row['bit'] and (b_row['bit2'] & c_row['bit']) > 0):new_row = {'cnt': b_row['cnt'] + 1,'bit': b_row['bit'] + c_row['bit'],'bit2': b_row['bit2'] & c_row['bit2']}# 检查是否已存在相同的bit组合if not any(existing['bit'] == new_row['bit'] for existing in b + new_rows):new_rows.append(new_row)changed = Trueb.extend(new_rows)# 找到cnt最大的行: select * from (select b.*,rank() over(order by cnt desc) rnk from b) where rnk=1if not b:returnmax_cnt = max(row['cnt'] for row in b)max_rows = [row for row in b if row['cnt'] == max_cnt]# 为每个最大集合生成点坐标字符串results = []for r in max_rows:points = []for a_row in A:# where bitand(r.bit, a.bit) > 0if r['bit'] & a_row['bit'] > 0:points.append(f"({a_row['x']},{a_row['y']})")# listagg within group(order by r.bit) - 这里按bit值排序可能没有意义,改为按坐标排序points.sort()results.append(''.join(points))# 输出结果print(f"最大集合大小: {max_cnt}")print(f"找到 {len(results)} 个最大集合:")#for i, result in enumerate(results, 1):#   print(f"{i}: {result}")if __name__ == "__main__":main()

以上程序的运行结果正确,但速度很慢,5x5个点,用时12秒。

C:\d>timer64 python sql2py.py
最大集合大小: 9
找到 70 个最大集合:Kernel  Time =     0.078 =    0%
User    Time =    11.984 =   99%
Process Time =    12.062 =   99%    Virtual  Memory =     10 MB
Global  Time =    12.072 =  100%    Physical Memory =     14 MB

查看上述代码,发现他不懂得递归CTE只能看到上一层递归的结果这个道理,每次都对整个b列表遍历,所以将相应遍历代码改为如下

    # 递归部分: 模拟递归CTEchanged = Truelast_cnt=0while changed:changed = Falsenew_rows = []last_cnt+=1temp_rows = [row for row in b if row['cnt'] == last_cnt]for b_row in temp_rows:

通过每次循环递增last_cnt,限制只在cnt等于last_cnt的子集中遍历,速度快了4倍,仍然不能令人满意

C:\d>timer64 python sql2py2.py
最大集合大小: 9
找到 70 个最大集合:Kernel  Time =     0.031 =    1%
User    Time =     2.703 =   98%
Process Time =     2.734 =   99%    Virtual  Memory =     10 MB
Global  Time =     2.750 =  100%    Physical Memory =     14 MB

再看代码,还有一段有误,这在SQL中并没有给出,属于画蛇添足,看来他不会优化程序,但是会添加自己的思想。

                    # 检查是否已存在相同的bit组合if not any(existing['bit'] == new_row['bit'] for existing in b + new_rows):

把上述判断去掉,速度快了几百倍, 继续测试6x6, 7x7也都很快。

C:\d>timer64 python sql2py2b.py
最大集合大小: 9
找到 70 个最大集合:Kernel  Time =     0.015 =   36%
User    Time =     0.015 =   36%
Process Time =     0.031 =   72%    Virtual  Memory =     10 MB
Global  Time =     0.043 =  100%    Physical Memory =     14 MBC:\d>timer64 python sql2py2b.py
最大集合大小: 11
找到 252 个最大集合:Kernel  Time =     0.015 =    6%
User    Time =     0.234 =   90%
Process Time =     0.250 =   96%    Virtual  Memory =     36 MB
Global  Time =     0.258 =  100%    Physical Memory =     40 MBC:\d>timer64 python sql2py2b.py
最大集合大小: 13
找到 924 个最大集合:Kernel  Time =     0.093 =    3%
User    Time =     2.968 =   96%
Process Time =     3.062 =  100%    Virtual  Memory =    317 MB
Global  Time =     3.061 =  100%    Physical Memory =    321 MB

前面的代码从b列表中反复筛选row['cnt'] == last_cnt的行,比较低效,考虑递归都在后面追加行,可以用列表的索引来处理

    # 递归部分: 模拟递归CTEchanged = Truelast_idx=0while changed:changed = Falsenew_rows = []cur_idx=len(b)-1for b_row in b[last_idx:]:# 保持源代码 last_idx=cur_idxb.extend(new_rows)

这个改动收益很少,7x7的集合只节省了0.1秒。

C:\d>timer64 python sql2py3b.py
最大集合大小: 13
找到 924 个最大集合:Kernel  Time =     0.093 =    3%
User    Time =     2.812 =   96%
Process Time =     2.906 =   99%    Virtual  Memory =    315 MB
Global  Time =     2.913 =  100%    Physical Memory =    319 MB

后记:
对于这个特定的需求,递归CTE的前面各层用过一次就可以丢弃,所以可以用新算出的层代替整个b列表,这种改动涉及的代码是最少的,效果相同。

        if new_rows != []:b=new_rows#b.extend(new_rows)

还能节省0.05秒, 内存也节省1半。

C:\d>timer64 python sql2py4.py
最大集合大小: 13
找到 924 个最大集合:Kernel  Time =     0.078 =    2%
User    Time =     2.765 =   96%
Process Time =     2.843 =   99%    Virtual  Memory =    145 MB
Global  Time =     2.863 =  100%    Physical Memory =    150 MB

用生成式语句代替循环和判断,

    # 递归部分: 模拟递归CTEchanged = Truewhile changed:changed = Falsenew_rows = [{'cnt': b_row['cnt'] + 1,'bit': b_row['bit'] + c_row['bit'],'bit2': b_row['bit2'] & c_row['bit2']}for b_row in b for c_row in C if c_row['bit'] > b_row['bit'] and (b_row['bit2'] & c_row['bit']) > 0]if new_rows != []:b=new_rows;changed = True

还能再快0.2秒

C:\d>timer64 python sql2py4b.py
最大集合大小: 13
找到 924 个最大集合:Kernel  Time =     0.140 =    5%
User    Time =     2.515 =   94%
Process Time =     2.656 =   99%    Virtual  Memory =    145 MB
Global  Time =     2.672 =  100%    Physical Memory =    150 MB
http://www.dtcms.com/a/528462.html

相关文章:

  • Zama TFHE 密文的Bootstrapping:小于1ms!
  • Spring Boot3零基础教程,函数式 Web 新特性,笔记51
  • Nginx----反向代理
  • 后端学习笔记--登录认证
  • 【开题答辩全过程】以 餐健一体化管理系统为例,包含答辩的问题和答案
  • 大型网站建设的难点是什么企业网站建设图片
  • 智能体通信协议详解:MCP/A2A/ANP
  • 公司大厅设计效果图大全站长工具seo综合查询
  • 【MYSQL】第二篇:SQL进阶指南:增删改查与性能优化实战手册
  • Spring Boot3零基础教程,Profile 配置文件 按环境分配置文件,笔记56
  • 小白python入门 - 7. Python分支与循环结构实战:从基础语法到代码逻辑解析
  • Chrony服务器同步时间服务器实验
  • 万互网站建站网站建设怎么提需求
  • 国产 做 视频网站陕西建筑培训网
  • [人工智能-大模型-69]:模型层技术 - 计算机处理问题的几大分支:数值型性问题、非数值型问题?
  • 0. Qt 安装及源码及报错
  • jQuery 事件方法详解
  • 基于Python大数据的热门游戏推荐系统
  • 网站如何做关健词收录网站应该如何推广
  • 网站应该如何进行优化微信企业网站 源码下载
  • LlamaFactory的docker-compose安装
  • RK3568笔记102:基于LVGL8的车载娱乐小平板设计
  • 技术随笔:Node.js ESM 中巧用 `-r dotenv/config` 解决环境变量异步加载问题
  • 网站做端口是什么有没有可以免费做试卷的网站_最好可以学会...
  • 游戏人物设计 简单思路 那任务简单说是显示的 完成任务是每个条件脚本自己判断 完成后发给任务脚本信息
  • 利用消息队列(MQ)设计:解耦与异步削峰的艺术
  • 自由学习记录(111)
  • ESP32使用笔记(基于ESP-IDF):小智AI的ESP32项目架构与启动流程全面解析
  • 网站建设 软文网站创作思路
  • 未来之窗昭和仙君(三十七)抽奖随机算法修仙体——东方仙盟筑基期