SQL优化之高效SQL语句
一、sql语句的执行步骤:
- 语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。
- 语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。
- 视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。
- 表达式转换,将复杂的 SQL 表达式转换为较简单的等效连接表达式。
- 选择优化器,不同的优化器一般产生不同的“执行计划”。
- 选择连接方式,ORACLE 有三种连接方式,对多表连接 ORACLE 可选择适当的连接方式。
- 选择连接顺序,对多表连接 ORACLE 选择哪一对表先连接,选择这两表中哪个表做为源数据表。
- 选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。
- 运行“执行计划”。
二、SQL Select语句完整的执行顺序:
- from子句组装来自不同数据源的数据;(from后面的表关联,是自右向左解析的,即在写SQL的时候,尽量把数据量大的表放在最右边来进行关联)
- where子句基于指定的条件对记录行进行筛选;(where条件的解析顺序是自下而上,从右到左的,即应把能筛选出大量数据的条件放在where语句的最下面)
- group by子句将数据划分为多个分组;
- 使用聚集函数进行计算;
- 使用having子句筛选分组;
- 计算所有的表达式;
- select 的字段;
- 使用order by对结果集进行排序;
- 选择指定数量或比例的行,返回给调用者。
SQL查询处理的步骤顺序如下:
在SQL语句中,第一个被处理的子句是FROM,而不是第一句SELECT。以上每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入;
三、SQL优化
对查询进行优化,应尽量避免全表扫描
(1)Where 语句
- 避免在WHERE子句中使用in,not in,or 或者having;
- 可以使用 exist 和not exist代替 in和not in;对连续数值可以使用between;
- 可以使用表链接代替 exist;
- Having可以用where代替,如果无法代替可以分两步处理。
- 应尽量避免在where子句中对字段进行函数操作;
- 尽量避免在 where 子句中对索引字段进行计算操作;
- 应尽量避免在 where 子句中使用 != 或 <> 操作符;
- 应尽量避免在 where 子句中对字段进行 null 值判断;
- 应尽量避免在 where 子句中使用 or 来连接条件;
- 否则将导致引擎放弃使用索引而进行全表扫描
(2)Select语句
- 尽量不要使用select * from table这种方式;把要查询的具体字段列出来,不要返回任何用不到的字段;
- 尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间;
(3)连接语句
- UNION 会将各查询子集的记录做比较,自动去掉重复记录,故比起UNION ALL 的速度,UNION的速度会慢很多。一般来说,如果使用UNION ALL能满足要求的话,尽量使用UNION ALL。
(4)Count (*)和 Count(1)以及 Count(column)的区别
- 一般情况,Select Count (*)和Select Count(1)返回结果一样;
- 假如表没有主键(Primary key),那么count(1)比count(*)快;
- 如果有主键,那主键作为count的条件时 count(主键)最快;
- 如果你的表只有一个字段,那count(*)最快;
- count(*) 跟 count(1) 的结果一样,都包括对NULL的统计,而count(column) 不包括NULL的统计
(5)查询的模糊匹配
- 尽量避免在一个复杂查询里面使用 LIKE '%parm1%' ,百分号会导致相关列的索引无法使用,最好不要用。
(6)复杂操作
- 部分UPDATE、SELECT 语句 写得很复杂(经常嵌套多级子查询),可以适当拆成几步,先生成一些临时表,再进行关联操作。
- 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
__EOF__

本文作者:苏浩-人生苦短-及时行乐
本文链接:https://www.cnblogs.com/Sulater/p/15838572.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/Sulater/p/15838572.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?