怎样写SQL语句可以提高数据库的性能

Azure数据库服务比较:SQL Database vs Cosmos DB 结构化数据场景:如订单管理、用户认证等需要强事务支持的业务非结构化/半结构化场景:如物联网设备日志、社交网络数据、实时推荐系统:基于传统关系型数据库(SQL Server)的云原生服务,支持ACID事务和复杂SQL查询Cosmos DB:全球分布式NoSQL数据库,支持多模型(文档、键值、图、宽列)和弹性扩展两者的架构设计哲学有何本质区别?数据建模和查询语言的差异如何影响开发体验?一致性、可用性、吞吐量的权衡模型如何选择?典型业务场景下的选型决策依据是什么?技术原理对比。 阅读详情

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

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

  (1) MERGE JOIN

  (2) NESTED LOOP JOIN

  (3) HASH JOIN

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

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

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

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

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

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

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

  原文出处:http://www.cnblogs.com/shuzhengyi/archive/2011/02/12/1952481.html

SQL高级语句-CREATE DATABASE 用于创建数据库。 CREATE DATABASE 语句 CREATE DATABASE 用于创建数据库。 SQL CREATE DATABASE 语法 CREATE DATABASE database_name SQL CREATE DATABASE 实例 现在我们希望创建一个名为 "my_db" 的数据库。 我们使用下面的 CREATE DATABASE 语句: CREATE 阅读详情

相关推荐

稳定运行的以Microsoft Azure SQL database数据库为数据源和目标的ETL性能变差时提高性能方法和步骤

在以为数据源和目标的 ETL(Extract, Transform, Load)过程中,性能问题可能会随着数据量的增加、查询复杂度的提升或系统负载的加重而逐渐变差。提高以 Microsoft Azure SQL Database 为数据源和目标的 ETL 性能需要综合考虑数据库查询优化、数据加载策略、并行处理、资源管理等方面。通过合适的索引、查询优化、批量处理、增量加载和数据库资源配置,可以显著提升 ETL 流程的性能。定期监控性能并根据负载情况进行调整,也是确保系统稳定运行的关键。

weixin_30777913的博客 1284

SQL优化篇:如何成为一位写优质SQL语句的绝顶高手

(Structured Query Language)标准结构化查询语言简称SQL,编写SQL语句是每位后端开发日常职责中,接触最多的一项工作,SQL是关系型数据库诞生的产物,无论是什么数据库,MySQL、Oracle、SQL Server、DB2、PgSQL....,只要还处于关系型数据库这个范畴,都会遵循统一的SQL标准,这句话简单来说也就是:无论什么关系型数据库,本质上SQL的语法都是相同的,因为它们都实现了相同的SQL标准,不同数据库之间仅支持的特性不同而已。

Java_zhujia的博客 1434

经典SQL语句大全(全面提升你的SQL水平)

经典SQL语句大全(全面提升你的SQL水平) 适用于初学者与中等水平的人

SQL优化篇:如何成为一位写优质SQL语句的绝顶高手!

你好,我是田哥写SQL语句不难,稍微系统学习过数据库相关技术的人都能做到,但想要写好SQL却也不是一件易事,在大多数编写SQL的时候,很多人都是以实现需求为原则去撰写的,当一条SQL写出来之后,只要能满足业务需求就行,不会考虑它有没有优化点,能不能让它跑的更快。面试不问java,问MySQL,如何破局?MySQL 开发规范,非常详细,建议收藏!而所谓的SQL优化,就是指将一条SQL写的更加简洁,让...

田维常 480

汽车级智能栅极驱动器深度解析 | 连载01:DRV871x-Q1系列产品架构与核心特性

集成度:单芯片集成多通道驱动器、电源管理、电流检测智能化:自适应控制算法,减少外部元件可靠性:多重保护机制,满足汽车级要求灵活性:SPI和硬件两种接口,适应不同应用需求。

VehSwHwDeveloper的博客 1151

UCD9081EVM电源时序管理:硬件配置与GUI操作全解析

电源时序管理是复杂电子系统设计的核心环节,它通过精确控制多路电源的上电/下电顺序,确保核心芯片免受浪涌电流或电压倒灌的损害。其原理基于状态机逻辑与电压监控,技术价值在于将硬连线时序转化为可编程配置,极大提升了系统可靠性与设计灵活性。在服务器、通信设备、工控系统等高可靠性应用场景中,时序控制器是实现稳定启动与故障保护的关键。本文以德州仪器UCD9081评估模块为例,深入剖析其硬件跳线配置与图形用户界面操作,涵盖I2C地址设置、电压监控分压计算、时序条件与故障响应策略等工程实践要点,帮助工程师快速掌握这一电源时

weixin_42696271的博客 302

SQL性能优化的47个小技巧,果断收藏!

路人发表于上海收录于合集#路人甲Java17个Java充电社,专注分享Java技术干货,包括多线程、JVM、SpringBoot、SpringCloud、Dubbo、Zookeeper、Redis、架构设计、微服务、消息队列、Git、面试题、程序员攻略、最新动态等。28篇原创内容公众号1、先了解MySQL的执行过程了解了MySQL的执行过程,我们才知道如何进行sql优化。客户端发送一条查询语句到服务器;服务器先查询缓存,如果命中缓存,则立即返回存储在缓存中的数据;

竹林幽深 735

手把手教你搞定MT6701磁编码器的SSI通信与CRC-6校验(附避坑代码)

本文详细介绍了MT6701磁编码器的SSI通信与CRC-6校验的实现方法,包括硬件连接、时序配置、数据读取和专用CRC-6算法。通过提供避坑代码和常见问题解决方案,帮助开发者快速掌握磁编芯片的调试技巧,确保通信稳定可靠。

weixin_30872337的博客 218

五个提升SQL语句性能的小窍门,进一步提升查询性能

在进行数据库操作时,优化SQL语句是提升性能和效率的关键步骤之一。无论是处理大规模数据还是简单的查询,优化SQL语句都可以明显改善系统的响应时间和资源利用率。

Z__7Gk的博客 1080

在 SAP S/4HANA Cloud Public Edition 中掌控 ABAP 生命周期管理:One-Off、Multi-Off 与 Scalable Delivery 的落地方法论

本文系统梳理了SAP S/4HANA Cloud Public Edition中ABAP扩展开发的三种生命周期管理模式:One-Off适用于企业内部扩展,通过Import Collection在三系统间流转;Multi-Off面向少量客户交付,基于gCTS和Git实现不连接系统间的传输;Scalable Delivery则将扩展产品化为add-on,支持规模化分发。文章结合RAP、OData等实际开发场景,对比分析了各模式的特点与适用边界,为国内团队提供了符合Public Cloud要求的开发与交付实践建议

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1495

把 SAP Activate 六个阶段看透:从项目落地到 SAP BTP 扩展与 AI 运营的一体化实践

摘要: SAP Activate 方法论常被误解为简单的项目阶段划分,实则是一套将业务目标、标准流程、系统配置和持续运营串联的实施控制体系。其六个阶段(Discover至Run)构成价值递进的实施通道,核心交付集中在Prepare到Deploy阶段。Discover阶段通过DDA评估确立项目方向与范围,Prepare阶段聚焦可执行性准备,Explore阶段采用Fit-to-Standard工作坊进行需求分层,Realize阶段基于前期决策进行配置与扩展开发。该方法论强调标准化优先,差异化需求通过SAP BT

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 2332

怎样写SQL语句可以提高数据库的访问性能【鸡蛋】

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

699

Amazon SES 移出沙盒完整指南 & 高通过率模板

AWS SES沙盒模式转正式模式申请指南 申请正式模式需通过AWS审核,常见被拒原因包括邮件用途不清晰、缺少退订机制或发送量不合理。人工申诉需登录AWS Support Center提交服务限额提升请求,填写详细的公司信息、邮件用途及合规措施。 高通过率申诉模板需包含: 公司信息:名称、网址及与AWS的合作情况。 邮件规范:明确类型(交易/营销)、退订链接及退信处理机制。 发送计划:合理预估发送量,确保合规。 关键点:真实信息、用途清晰、退订机制完善、发送量合理。首次被拒可修改后重新提交。

xianyinsuifeng的博客 328

在程序开发中怎样写SQL语句可以提高数据库的性能

以下内容是公司dba总结。  1、 首先要搞明白什么叫执行计划?   执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生的,比如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用“全表扫描”方式。   可见,执行计划并不是固定...

weixin_34388207的博客 179

第一章 EB安装

1.DemoWorkspace 是基于EB当前组件配置下的例程,包含了启动文件和中断服务函数以及组件demo。2.Mclsar 下存放的是EB的插件包和静态MCAL的驱动文件。

舊梦的博客 1956

网络流量异常信息分析方法研究

本课题针对网络安全中网络流量异常的分析方法进行研究,提出一种基于机器学习和深度学习的异常检测算法。该算法采用卷积神经网络(CNN)和长短时记忆神经网络(LSTM)结合的方式,通过训练得到二分类模型,从而实现对网络流量异常的检测。随着互联网的飞速发展,网络攻击事件日益增多,网络安全问题成为了亟待解决的问题之一。常见的网络攻击手段包括 DDoS 攻击、SQL 注入、XSS 攻击等,这些攻击手段可能导致网络系统发生异常,给网络运维、数据安全带来极大的挑战。

肥晨开发的学习之路 1035

Python通过ibm_db模块进行DB2数据库SQL语句执行及结果返回

执行SQL语句 方法一: 语法: 调用ibm_db.prepare()函数并传递以下参数: 1.从ibm_db.connect()或ibm_db.pconnect()函数返回的有效数据库连接资源; 2.包含SQL语句的字符串,包括需要变量输入的任何列或谓词值的参数标记(?)。该字符串可以包含由XMLQUERY子句包装的XQuery表达式 3.ibm_db.execute()执行SQL语句 im...

weixin_42970378的博客 8895

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: SQLite的SQL语法
下一篇: 数据库中如何多次join同一个表
cll131421
博客等级 码龄19年 68粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值