广告
返回顶部
首页 > 资讯 > 数据库 >怎么优化SQL查询语句
  • 219
分享到

怎么优化SQL查询语句

2024-04-02 19:04:59 219人浏览 八月长安
摘要

这篇文章主要讲解了“怎么优化sql查询语句”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么优化SQL查询语句”吧!1、 首先要搞明白什么叫执行计划?执行计

这篇文章主要讲解了“怎么优化sql查询语句”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么优化SQL查询语句”吧!

1、 首先要搞明白什么叫执行计划?

执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个  10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用  “全表扫描”方式。

可见,执行计划并不是固定的,它是“个性化的”。产生一个正确的“执行计划”有两点很重要:

(1) SQL语句是否清晰地告诉查询优化器它想干什么?

(2) 查询优化器得到的数据库统计信息是否是***的、正确的?

2、 统一SQL语句的写法

对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。

select*from dual  select*From dual

其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析。生成2个执行计划。所以作为程序员,应该保证相同的查询语句在任何地方都一致,多一个空格都不行!

3、 不要把SQL语句写得太复杂

我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A4纸这么长。一般来说这么复杂的语句通常都是有问题的。我拿着这2页长的SQL语句去请教原作者,结果他说时间太长,他一时也看不懂了。可想而知,连原作者都有可能看糊涂的SQL语句,数据库也一样会看糊涂。

一般,将一个Select语句的结果作为子集,然后从该子集中再进行查询,这种一层嵌套语句还是比较常见的,但是根据经验,超过3层嵌套,查询优化器就很容易给出错误的执行计划。因为它被绕晕了。像这种类似人工智能的东西,终究比人的分辨力要差些,如果人都看晕了,我可以保证数据库也会晕的。

另外,执行计划是可以被重用的,越简单的SQL语句被重用的可能性越高。而复杂的SQL语句只要有一个字符发生变化就必须重新解析,然后再把这一大堆垃圾塞在内存里。可想而知,数据库的效率会何等低下。

4、 使用“临时表”暂存中间结果

简化SQL语句的重要方法就是采用临时表暂存中间结果,但是,临时表的好处远远不止这些,将临时结果暂存在临时表,后面的查询就在tempdb中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享”阻塞“更新锁”,减少了阻塞,提高了并发性能。

5、 OLTP系统SQL语句必须采用绑定变量

select*from orderheader where changetime >'2010-10-20 00:00:01'  select*from orderheader where changetime >'2010-09-22 00:00:01'

以上两句语句,查询优化器认为是不同的SQL语句,需要解析两次。如果采用绑定变量

select*from orderheader where changetime >@chgtime

@chgtime变量可以传入任何值,这样大量的类似查询可以重用该执行计划了,这可以大大降低数据库解析SQL语句的负担。一次解析,多次重用,是提高数据库效率的原则。

6、 绑定变量窥测

事物都存在两面性,绑定变量对大多数OLTP处理是适用的,但是也有例外。比如在where条件中的字段是“倾斜字段”的时候。

“倾斜字段”指该列中的绝大多数的值都是相同的,比如一张人口调查表,其中“民族”这列,90%以上都是汉族。那么如果一个SQL语句要查询30岁的汉族人口有多少,那“民族”这列必然要被放在where条件中。这个时候如果采用绑定变量@nation会存在很大问题。

试想如果@nation传入的***个值是“汉族”,那整个执行计划必然会选择表扫描。然后,第二个值传入的是“布依族”,按理说“布依族”占的比例可能只有万分之一,应该采用索引查找。但是,由于重用了***次解析的“汉族”的那个执行计划,那么第二次也将采用表扫描方式。这个问题就是著名的“绑定变量窥测”,建议对于“倾斜字段”不要采用绑定变量。

7、 只在必要的情况下才使用begin tran

SQL Server中一句SQL语句默认就是一个事务,在该语句执行完成后也是默认commit的。其实,这就是begin  tran的一个最小化的形式,好比在每句语句开头隐含了一个begin tran,结束时隐含了一个commit。

有些情况下,我们需要显式声明begin tran,比如做“插、删、改”操作需要同时修改几个表,要求要么几个表都修改成功,要么都不成功。begin tran  可以起到这样的作用,它可以把若干SQL语句套在一起执行,***再一起commit。好处是保证了数据的一致性,但任何事情都不是***无缺的。Begin  tran付出的代价是在提交之前,所有SQL语句锁住的资源都不能释放,直到commit掉。

可见,如果Begin tran套住的SQL语句太多,那数据库的性能就糟糕了。在该大事务提交之前,必然会阻塞别的语句,造成block很多。

Begin tran使用的原则是,在保证数据一致性的前提下,begin tran  套住的SQL语句越少越好!有些情况下可以采用触发器同步数据,不一定要用begin tran。

8、 一些SQL查询语句应加上nolock

在SQL语句中加nolock是提高SQL  Server并发性能的重要手段,在oracle中并不需要这样做,因为oracle的结构更为合理,有undo表空间保存“数据前影”,该数据如果在修改中还未commit,那么你读到的是它修改之前的副本,该副本放在undo表空间中。这样,oracle的读、写可以做到互不影响,这也是oracle  广受称赞的地方。SQL Server  的读、写是会相互阻塞的,为了提高并发性能,对于一些查询,可以加上nolock,这样读的时候可以允许写,但缺点是可能读到未提交的脏数据。使用  nolock有3条原则。

(1) 查询的结果用于“插、删、改”的不能加nolock !

(2) 查询的表属于频繁发生页分裂的,慎用nolock !

(3) 使用临时表一样可以保存“数据前影”,起到类似oracle的undo表空间的功能,

能采用临时表提高并发性能的,不要用nolock 。

9、 聚集索引没有建在表的顺序字段上,该表容易发生页分裂

比如订单表,有订单编号orderid,也有客户编号contactid,那么聚集索引应该加在哪个字段上呢?对于该表,订单编号是顺序添加的,如果在orderid上加聚集索引,新增的行都是添加在末尾,这样不容易经常产生页分裂。然而,由于大多数查询都是根据客户编号来查的,因此,将聚集索引加在contactid上才有意义。而contactid对于订单表而言,并非顺序字段。

比如“张三”的“contactid”是001,那么“张三”的订单信息必须都放在这张表的***个数据页上,如果今天“张三”新下了一个订单,那该订单信息不能放在表的***一页,而是***页!如果***页放满了呢?很抱歉,该表所有数据都要往后移动为这条记录腾地方。

SQL Server的索引和Oracle的索引是不同的,SQL  Server的聚集索引实际上是对表按照聚集索引字段的顺序进行了排序,相当于oracle的索引组织表。SQL  Server的聚集索引就是表本身的一种组织形式,所以它的效率是非常高的。也正因为此,插入一条记录,它的位置不是随便放的,而是要按照顺序放在该放的数据页,如果那个数据页没有空间了,就引起了页分裂。所以很显然,聚集索引没有建在表的顺序字段上,该表容易发生页分裂。

曾经碰到过一个情况,一位哥们的某张表重建索引后,插入的效率大幅下降了。估计情况大概是这样的。该表的聚集索引可能没有建在表的顺序字段上,该表经常被归档,所以该表的数据是以一种稀疏状态存在的。比如张三下过20张订单,而最近3个月的订单只有5张,归档策略是保留3个月数据,那么张三过去的  15张订单已经被归档,留下15个空位,可以在insert发生时重新被利用。在这种情况下由于有空位可以利用,就不会发生页分裂。但是查询性能会比较低,因为查询时必须扫描那些没有数据的空位。

重建聚集索引后情况改变了,因为重建聚集索引就是把表中的数据重新排列一遍,原来的空位没有了,而页的填充率又很高,插入数据经常要发生页分裂,所以性能大幅下降。

对于聚集索引没有建在顺序字段上的表,是否要给与比较低的页填充率?是否要避免重建聚集索引?是一个值得考虑的问题!

10、加nolock后查询经常发生页分裂的表,容易产生跳读或重复读

加nolock后可以在“插、删、改”的同时进行查询,但是由于同时发生“插、删、改”,在某些情况下,一旦该数据页满了,那么页分裂不可避免,而此时nolock的查询正在发生,比如在第100页已经读过的记录,可能会因为页分裂而分到第101页,这有可能使得nolock查询在读101页时重复读到该条数据,产生“重复读”。同理,如果在100页上的数据还没被读到就分到99页去了,那nolock查询有可能会漏过该记录,产生“跳读”。

上面提到的哥们,在加了nolock后一些操作出现报错,估计有可能因为nolock查询产生了重复读,2条相同的记录去插入别的表,当然会发生主键冲突。

11、使用like进行模糊查询时应注意

有的时候会需要进行一些模糊查询比如

select*from contact where username like ‘%yue%’

关键词%yue%,由于yue前面用到了“%”,因此该查询必然走全表扫描,除非必要,否则不要在关键词前加%,

12、数据类型的隐式转换对查询效率的影响

sql server2000的数据库,我们的程序在提交sql语句的时候,没有使用强类型提交这个字段的值,由sql server  2000自动转换数据类型,会导致传入的参数与主键字段类型不一致,这个时候sql server  2000可能就会使用全表扫描。Sql2005上没有发现这种问题,但是还是应该注意一下。

13、SQL Server 表连接的三种方式

(1) Merge Join

(2) Nested Loop Join

(3) Hash Join

SQL Server 2000只有一种join方式——Nested Loop  Join,如果A结果集较小,那就默认作为外表,A中每条记录都要去B中扫描一遍,实际扫过的行数相当于A结果集行数x  B结果集行数。所以如果两个结果集都很大,那Join的结果很糟糕。

SQL Server 2005新增了Merge  Join,如果A表和B表的连接字段正好是聚集索引所在字段,那么表的顺序已经排好,只要两边拼上去就行了,这种join的开销相当于A表的结果集行数加上B表的结果集行数,一个是加,一个是乘,可见merge  join 的效果要比Nested Loop Join好多了。

如果连接的字段上没有索引,那SQL2000的效率是相当低的,而SQL2005提供了Hash  join,相当于临时给A,B表的结果集加上索引,因此SQL2005的效率比SQL2000有很大提高,我认为,这是一个重要的原因。

总结一下,在表连接时要注意以下几点:

(1) 连接字段尽量选择聚集索引所在的字段

(2) 仔细考虑where条件,尽量减小A、B表的结果集

(3) 如果很多join的连接字段都缺少索引,而你还在用SQL Server 2000,赶紧升级吧。

感谢各位的阅读,以上就是“怎么优化SQL查询语句”的内容了,经过本文的学习后,相信大家对怎么优化SQL查询语句这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

您可能感兴趣的文档:

--结束END--

本文标题: 怎么优化SQL查询语句

本文链接: https://www.lsjlt.com/news/59216.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么优化SQL查询语句
    这篇文章主要讲解了“怎么优化SQL查询语句”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么优化SQL查询语句”吧!1、 首先要搞明白什么叫执行计划执行计划...
    99+
    2022-10-18
  • sql查询语句优化
    sql查询语句优化 1、对查询进行优化,应尽量避免全表扫描 a、 where 及 order by 涉及的列上建立索引 b、 尽量避免在 where 子句中对字段进行 null 值判断,可以将null值设置默认值0等,如...
    99+
    2016-05-19
    sql查询语句优化 数据库入门 数据库基础教程 数据库 mysql
  • MySQL中怎么优化SQL查询语句
    这期内容当中小编将会给大家带来有关MySQL中怎么优化SQL查询语句,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、应尽量避免在 where 子句中使用!=或...
    99+
    2022-10-18
  • sql语句查询慢如何优化
    优化 SQL 查询性能的方法有很多,以下是一些常见的优化技巧:1. 索引优化:使用适当的索引可以大大提高查询性能。考虑创建索引以支持...
    99+
    2023-09-27
    sql
  • SQL查询语句怎么写
    这篇文章主要为大家展示了“SQL查询语句怎么写”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SQL查询语句怎么写”这篇文章吧。查询所有列Select ...
    99+
    2022-10-19
  • MySQL中怎么优化查询语句
    这篇文章将为大家详细讲解有关MySQL中怎么优化查询语句,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。  MySQL常用30种SQL查询语句优化方法  1、...
    99+
    2022-10-18
  • mysql查询语句优化
     这篇说下mysql查询语句优化 是否请求了不需要的数据 典型案例:查询不需要的记录,多表关联时返回全部列,总是取出全部列,重复查询相同的数据。 是否在扫描额外的记录 ...
    99+
    2022-05-11
    mysql
  • MySQLexplain根据查询计划去优化SQL语句
    目录一、什么是MySQL explain二、如何使用MySQL explainMySQL是一种常见的关系型数据库管理系统,常被用于各种应用程序中存储数据。当涉及到大量的数据时,数据库...
    99+
    2023-05-14
    MySQL explain查询计划去优化SQL语句 explain优化SQL语句
  • SQL语句怎么优化
    这篇文章运用简单易懂的例子给大家介绍SQL语句怎么优化,代码非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、常见的SQL实践(1)负向条件查询不能使用索引select * fro...
    99+
    2022-10-18
  • T-SQL查询语句
        SQL语言中最主要、最核心的部分是它的查询功能。查询语句用来对已经存在于数据库的数据按照特定的组合、条件表达式或次序进行检索,使用SELECT语句来完...
    99+
    2022-10-18
  • sql条件查询语句怎么写
    SQL条件查询语句的写法如下:SELECT 列名FROM 表名WHERE 条件;其中,列名是要查询的字段名,可以是单...
    99+
    2023-10-10
    sql
  • sql分页查询语句怎么写
    SQL分页查询语句可以使用LIMIT关键字来实现。具体语法如下:SELECT 列名FROM 表名LIMIT 开始位置, 查询...
    99+
    2023-08-23
    sql
  • SQL模糊查询语句怎么写
    这篇文章给大家分享的是有关SQL模糊查询语句怎么写的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。SQL模糊查询语句一般模糊语句语法如下:SELECT 字段&nb...
    99+
    2022-10-18
  • MySQL常用30种SQL查询语句优化方法
    引言 在开发和维护MySQL数据库时,优化SQL查询语句是提高数据库性能和响应速度的关键。通过合理优化SQL查询,可以减少数据库的负载,提高查询效率,为用户提供更好的用户体验。本文将介绍常用的30种MySQL SQL查询优化方法,并通过实际...
    99+
    2023-10-23
    mysql sql 数据库
  • MySQL explain根据查询计划去优化SQL语句
    目录一、什么是mysql explain二、如何使用MySQL explainMySQL是一种常见的关系型数据库管理系统,常被用于各种应用程序中存储数据。当涉及到大量的数据时,数据库查询的性能就成了关键因素,这时就需要M...
    99+
    2023-04-07
    MySQL explain查询计划去优化SQL语句 explain优化SQL语句
  • MySQL explain根据查询计划去优化SQL语句
    本篇内容介绍了“MySQL explain根据查询计划去优化SQL语句”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!MySQL是一...
    99+
    2023-07-05
  • sql server查询语句阻塞优化性能问题怎么解决
    这篇文章主要介绍“sql server查询语句阻塞优化性能问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“sql server查询语句阻塞优化性能问题怎么解决”文章能帮...
    99+
    2023-06-29
  • SQL UPDATE语句怎么优化
    要优化SQL UPDATE语句,可以考虑以下几个方面:1. 限制更新的行数:如果你只需要更新部分记录,可以使用WHERE子句...
    99+
    2023-09-05
    SQL
  • sql的基础语句-sql的查询语句select
     SQL查询语句介绍--select语句1.简单的select查询语句1.1 查行SQL> select * from emp;1.2 查列SQL> select ...
    99+
    2022-10-18
  • 常用sql语句查询
    oracle常用经典SQL查询 常用SQL查询:   查看表空间的名称及大小   select t.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_size from dba...
    99+
    2019-10-10
    常用sql语句查询 数据库入门 数据库基础教程 数据库 mysql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作