暂无图片
暂无图片
6
暂无图片
暂无图片
暂无图片

【专家观点】罗敏:从理论到真实SQL,感受DeepSeek如何做性能优化

原创 墨天轮编辑部 3天前
383

编者按:近年来,数据库性能优化一直是DBA群体关注的焦点,近期也有不少DBA尝试使用DeepSeek来提升数据库的性能,那么它的实际效果究竟如何?是否存在局限?怎样才能用好它?我们特别邀请到业内知名的优化专家罗敏老师通过多个案例进行了分析解读,望对大家有所助益。

作者简介

罗敏:数据库资深技术专家,《品悟性能优化》、《感悟Oracle核心技术》和《Oracle数据库技术服务案例精选》等数据库畅销书作者。


最近DeepSeek火热出圈,正成为各行各业热门话题。百聊不如一试,暂且不关注DeepSeek深奥的神经网络模型、大语言模型等内部机制,我近日从自己的专业领域出发也开启了DeepSeek探索之旅。本文我将以数据库性能优化为大话题,逐步深入到具体的SQL语句性能优化,梳理总结DeepSeek的深奥和神奇。

第一问:如何进行数据库性能优化

当我在DeepSeek中输入“数据库性能优化”之后,令DeepSeek思索了一定时间,并感慨道:“嗯,用户问的是数据库性能优化,这个题目挺大的,得好好理清楚思路。”24秒之后,DeepSeek就洋洋洒洒给出了数百行的回复,涵盖优化步骤、查询优化、硬件配置、事务和锁、定期维护索引、统计数据更新、归档历史数据、查询缓存、连接池、批量操作等方面总体性思路。

我的感受:我的问题的确太大,DeepSeek的回答也的确很泛泛,但DeepSeek很努力,不仅希望包括数据库性能优化领域的方方面面,而且也在尝试给出一些具体建议。我认为DeepSeek回复的这些建议,确实就是我们在性能优化实际工作中应遵循的方法论,以及需要全面综合考虑问题的视野。再者,尽管这些建议并不能涵盖性能优化所有领域,但我们业内同行们是否能完全掌握呢?例如有多少DBA在定期重建索引,从而提升索引访问性能呢?

第二问:如何进行SQL语句性能优化

众所周知,应用性能优化在数据库性能优化领域中作用最大。当我再将问题进一步细化成 “SQL语句性能优化”时, DeepSeek给到了6个方面的回复:

  • 优化SQL语句本身,包括避免使用 SELECT *、减少子查询、避免使用OR条件、使用 EXISTS替代IN、避免在WHERE子句中使用函数等。
  • 索引优化,包括创建合适的索引(单字段和复合索引)、避免过度索引、使用覆盖索引、定期维护索引等。
  • 数据库设计优化,包括规范化与反规范化的平衡、分区表设计、使用物化视图等。
  • 数据库参数优化,包括调整缓冲区大小、调整连接数、优化日志设置等。
  • 监控与分析,包括使用执行计划、启用慢查询日志、使用性能监控工具等。
  • 高级优化技术,包括并行查询、使用提示(Hints)、分布式数据库等。

我的感受:这次DeepSeek的回答从全局性而言可谓高屋建瓴、面面俱到,但这些建议是否放之四海而皆准呢?针对具体的SQL语句,DeepSeek是否能精准定位问题并给出恰如其分的建议呢?有待进一步探索。此外,依据我的多年实践经验,DeepSeek努力给出的一些具体建议还是值得商榷,例如exist语句未必比in语句更快,要看具体的谓词条件位于主语句还是子语句。

总之,DeepSeek的思索结果貌似很全面,但在实际运用中应该仔细斟酌其合理性。到此可以说我初识DeepSeek的风格:很努力、面面俱到,但泛泛而谈。接下来我该将SQL真实语句扔给DeepSeek,验证其真金白银了。

第三问实战:对一条简单SQL语句进行优化

针对如下一条语句:

select * from sales_227 where (PROD_ID = 13 or cust_id = 987) and time_id between sysdate - 9900 and sysdate - 9800

我的优化方案是充分利用组合索引性能,分别创建sales_227(PROD_ID, time_id)和sales_227(cust_id, time_id)两个组合索引。

我在与DeepSeek的多次沟通中,DeepSeek只是给出了创建包含三个字段的组合索引和三个单字段索引的建议,最后我直接将这两个组合索引告诉DeepSeek,DeepSeek才给出肯定答复。除此之外,DeepSeek还给出了将or操作改为union all语句,是否需要分区、统计数据采集,甚至考虑了是否需要使用物化视图的建议。

我的感受:我的第一感受是与其说DeepSeek在帮我,不如说我在循序渐进地指导DeepSeek如何做优化,到最后我认为DeepSeek还是没有深刻理解Oracle优化器已经将or操作转换成了UNION ALL操作,并且对两个子语句都合理使用了组合索引的内部技术原理。

第二感受就是DeepSeek的勤奋、努力,的确可以弥补我们常人思维中的缺失和短路,但这种胡子眉毛一把抓、没有针对性和重点的风格,反而可能干扰了我们对最关键问题的快速、精准分析能力。

目前我的印象是AI就是不知疲倦的机器在进行计算,但尚缺乏人类对问题定位和分析的敏锐性、灵动力

第四问实战:对一条复杂SQL语句进行优化

接下来我准备来个更复杂的真实 SQL语句,该语句来自我即将出版的新书中“从一条SQL语句看当下应用开发的典型问题”一文。这就是那条语句全貌:

select NVL(count(c.BIZDATA_CD), 0) as bizSum, NVL(sum(case when sysdate - b.LSMOD_DATE < 4 / 24 then 1 end), 0) as bizInFourHour, … … from ssp_arch_bizstatus b left join ssp_arch_bizdata c on c.BIZDATA_CD = b.BIZDATA_CD where b.SQBILL_STATE = '34' and b.SQARCH_STATE != '2' AND NOT EXISTS (SELECT 1 FROM SSP_ARCH_BIZHIS h WHERE h.SQ_CD = c.BIZDATA_CD AND h.SQBILL_STATE = '45') and c.SQ_DATE >= to_date(:1, 'yyyy-mm-dd hh24:mi:ss') and exists (select 1 from SSP_ARCH_WHOUSECD_PREF_EMPPAGE a left JOIN ssp_arch_warehouse_cd_pref b ON a.WAREHOUSE_CD_PREF = b.WAREHOUSE_CD_PREF WHERE c.PROCENT_CD = a.PROCENT_CD and b.ORGANIZATION_CD = :2) and exists (select 1 from SSP_ARCH_WHOUSECD_PREF_EMPPAGE a left JOIN ssp_arch_warehouse_cd_pref b ON a.WAREHOUSE_CD_PREF = b.WAREHOUSE_CD_PREF WHERE c.PROCENT_CD = a.PROCENT_CD and b.ORGANIZATION_CD = :3 and b.WAREHOUSE_CD_PREF = :4)

现有执行计划就不重复了,一眼望去的主要问题是出现了对SSP_ARCH_BIZHIS表的全表扫描。

我的分析:

  • 第一个问题:重复的业务逻辑问题

该语句的两个exists 子查询存在重复业务逻辑, 即第二个exists 子查询多了一个b.WAREHOUSE_CD_PREF = :4条件,也就是说第二个exists子查询的取值是第一个exists子查询取值的子集,因此可去掉第一个exists子查询。

  • 第二个问题:缺乏复合索引问题

经深入分析, 发现该语句缺乏两个复合索引, 即建议创建 SSP_ARCH_BIZHIS(SQ_CD, SQBILL_STATE) 和 ssp_arch_bizdata(PROCENT_CD,SQ_DATE) 复合索引。

  • 第三个问题:过度设计历史表问题

从SSP_ARCH_BIZHIS表名就可分析出该表是个历史表,如果取消历史表设计,语句将进一步简化。

  • 第四个问题:缺乏分区设计问题

该语句主要访问的SSP_ARCH_BIZDATA和SSP_ARCH_BIZHIS表已经分别达到32GB和28GB,记录数分别达到5000多万和1.5亿条,因此建议将这两张表进行分区,相关索引也进行分区索引设计,将是提升性能和数据可管理性的重要优化手段。

  • 第五个问题:绑定变量使用问题

由于该语句查询条件范围多变、记录分布不均匀,导致执行计划多变,而该语句在3个小时内只执行了15次,因此我的建议是该语句不使用绑定变量,而是全部使用常量,从而避免Oracle采用ACS技术动态生成执行计划,简化执行计划生成过程,确保优化器根据实际的常量值,生成最优的执行计划。

DeepSeek的答案简版梳理:

首先,DeepSeek也分析出“当前存在两个几乎相同的EXISTS子查询,只是参数不同”,并建议“合并为一个子查询,减少重复表扫描”,还给出了简化后的语句。

其次,DeepSeek给出了若干索引优化建议,包括创建ssp_arch_bizstatus(SQBILL_STATE, SQARCH_STATE, BIZDATA_CD) 、 ssp_arch_bizdata(BIZDATA_CD, SQ_DATE, PROCENT_CD) 、SSP_ARCH_BIZHIS(SQ_CD, SQBILL_STATE)、ssp_arch_warehouse_cd_pref(WAREHOUSE_CD_PREF,ORGANIZATION_CD)复合索引。

第三,DeepSeek指出语句中的sysdate - b.LSMOD_DATE < 4 / 24 编写问题,即对字段`LSMOD_DATE`进行了计算,将导致索引失效。

最后,DeepSeek还是放心不下,让我仔细分析执行计划,是否有全表扫描,还让我注意统计数据是否过期,甚至还担心绑定变量的传入值与字段类型是否一致。

对比分析

此外我也运用Oracle自动化优化工具-SQL Tuning Advisor进行了分析,下面是三方分析结果的对比。

问题分类 人工分析情况 SQL Tuning Advisor分析情况 DeepSeek分析情况
重复的业务逻辑问题 分析出来 未分析出来 分析出来
缺乏复合索引问题 更精准分析结果 不精准,过度优化 不精准,过度优化
过度设计历史表问题 分析出来 未分析出来 未分析出来
缺乏分区设计问题 分析出来 未分析出来 未分析出来
绑定变量使用问题 分析出来 未分析出来 未分析出来

首先,在语句中存在两个exists的重复业务逻辑问题,我和DeepSeek都分析出来了,而Oracle没有分析出来。这个问题是纯语法性问题,应该不难分析,说明Oracle还有提升空间。

其次,由于我在现场详细分析了语句执行计划,尤其是统计了相关表的数据分布,而且经过测试验证,因此我的复合索引优化建议最为精准。而DeepSeek和SQL Tuning Advisor给出的复合索引建议都不精准,甚至给出了多余的建议。

在过度设计历史表、缺乏分区设计、绑定变量使用三个问题方面,SQL Tuning Advisor和DeepSeek完全无感,我想不仅是因为他们无法访问到真实数据,而且这些优化建议是源于对业务逻辑的理解,甚至是个人经验的发挥。

总之,尽管可喂给DeepSeek执行计划、表结构、数据量级等更多信息,甚至可部署DB Agent软件在客户系统,帮助 DeepSeek给出更贴近真实情况、更有价值的建议,但那些依赖人的经验、与业务的沟通和融合能力等才能做出的抉择,还是DeepSeek难以胜任的

AI对人类社会发展的意义

AI正如火如荼,特别是DeepSeek的横空出世,令全球各方面人士都在关注AI技术对人类社会发展的意义。当今世界的人们面对AI技术也形成了泾渭分明的两种观点,一种观点认为DeepSeek、AI将无所不能,并将替代人类大部分工作。例如部分数据库同行就认为DeepSeek不仅能胜任DBA大部分工作,而且可以自动生成应用程序和代码,未来DeepSeek会砸了很多同行饭碗。另一种观点则恰恰相反,认为AI只能从事一些简单、重复性工作,难堪大任,仅仅作为工作、生活中的辅助工具而已。

以我对DeepSeek的初探,尤其是基于Oracle在自动化、智能化技术数十年发展的体验,我持比较中庸、乐观的态度。即一方面我会积极拥抱AI等新技术,另一方面我相信人的睿智、灵动性、情感是冰冷的机器、AI算法、大模型等无法替代的。

总之,我将DeepSeek和AI理解成不断发展和完善的工具、字典、百科全书,甚至是工作方法论和生活助手。人类社会未来如何发展?下面就是我理解的愿景:

image.png

本文为墨天轮社区特别邀稿,内容原创,仅代表作者观点,欢迎大家交流、讨论。文章现已收录至合辑《墨天轮专家邀稿合辑:论道数据库 解读新发展》,如需转载请联系作者或墨天轮官方。

最后修改时间:2025-03-06 16:59:54
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论