高性能SQL-数据库性能优化

news2024/9/28 19:16:20

数据库性能优化涉及各个方面,本文就总多个角度介绍一下数据库性能优化的方法

1.表设计

聚集索引

一个表只能有一个聚集索引,数据在磁盘上的排练顺序与聚集索引一致,根据业务仔细设定聚集索引,值递增的不可修改的字段才能设置聚集索引: 自增Id,递增的单号,创建日期等
应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

主键

一个表主键经常被其他表引用,也就经常出现在连接条件和Where条件中,合适的主键对于SQL性能起到了关键的作用
如果业务上已经有唯一的递增的不可修改的,关键业务字段,优先考虑使用业务字段做主键,例如订单的单号,单号符合 唯一,递增,不可修改,长度固定,关键业务,这些特性,非常适合做主键
其次考虑自增id,检索的效率最高
主键默认是聚集索引

创建时间

创建时间唯一,递增,不可修改,经常用于where条件中进行范围检索,非常适合做聚集索引
要先设置聚集索引,再设置主键,才不会被主键默认占用聚集索引

非聚集索引

就是普通的索引,可准确预估到会高频出现在where条件和连接条件中的字段可以设置索引,否则不要设置,待出现性能瓶颈后,分析sql后再设置

null与字符串默认空字符串

在where条件中出现null值判断会破坏索引的使用,所以在表设计时就尽量把列设置为not null , 空字符串可以存储’’ ,其他类型没有通用的替代方案, 例如 枚举可以用-1代表空值

外键

不要设置外键!!
不要设置外键!!
不要设置外键!!
外键只作为业务概念存在,不做数据库约束,否则会带来运维灾难

建表的例子

--表说明xxxxx  
IF OBJECT_ID ('SysUser', 'U') IS NULL  
   BEGIN  
      CREATE TABLE [dbo].[SysUser]  
      (  
         [Id]                     BIGINT IDENTITY (1, 1) NOT NULL,  
         [UserCode]                   NVARCHAR (32) NOT NULL,  
         [PhoneNumber]            NVARCHAR (32) NOT NULL,  
         [Password]               NVARCHAR (128) NOT NULL,  
         [UserName]               NVARCHAR (256) NOT NULL,  
         [CreationTime]           DATETIME NOT NULL,  
         [CreatorUserId]          BIGINT NULL,  
         [LastLoginTime]          DATETIME NULL,  
         [LastModificationTime]   DATETIME NULL,  
         [LastModifierUserId]     BIGINT NULL,  
         [IsActive]               BIT NOT NULL  
      );  
  
      --添加聚集索引,根据业务仔细设定,值递增的字段才能设置聚集索引 
      CREATE CLUSTERED INDEX IX_SysUser_CreationTime  
         ON SysUser (CreationTime);  
  
      --添加非聚集索引  
      CREATE NONCLUSTERED INDEX IX_SysUser_CreatorUserId  
         ON SysUser (CreatorUserId);  
  
      --添加默认值  
      ALTER TABLE SysUser  ADD CONSTRAINT DF_SysUser_CreationTime DEFAULT GetDate() FOR CreationTime  
  
      --添加主键  
      ALTER TABLE SysUser ADD CONSTRAINT PK_SysUser   PRIMARY KEY (Id);  
   END  
GO  

2.索引

  • 出现性能瓶颈的时候,先考虑SQL有没有优化的空间,优化后再考虑在 where 及 order by 涉及的列上建立索引
  • 索引固然可以提高相应的 select 的效率,但同时也降低了 insert 、 update 及 delete 的效率, 所以不是索引不是越多越好
  • 数据量大的表,维护索引的开销也大, 建索引要慎重
  • 数据量小的表用不着建索引
  • 索引列存在大量重复数据时效果不明显, 此时不应该建索引, 例如sex列

3.Where

like/Or/In

引起减少引起全表扫描的动作: or、like(‘%%’)、in和not in (
用左匹配(走索引),不用右匹配,不用全匹配(不走索引):Where UserName like ‘abc%’
很多时候用exists,between替代 in 是一个好的选择:
Where num in(select num from b)
用下面的语句替换:
Where exists(select 1 from b where num=a.num)

不等于

尽量不用not 或 =! 或 <> ,将放弃索引

运算

不要在 where 子句中的“=”左边进行函数、算术运算、类型转换或其他表达式运算,否则系统将可能无法正确使用索引

函数

尽量避免在where子句中对字段进行函数操作,否则将导致全表扫描。
例如: Where substring(name,1,3) = ‘abc’
应改为Where name like ‘abc%’

计算

尽量避免在where子句中对字段进行表达式操作,否则会导致全表扫描。可以把字段从表达式中移除走,
例如: Where num/2 = 100
应改为 Where num = 100 *2
条件顺序
在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

4.Join

少用左连接,多用内连接
left join 比 inner join 消耗更多的资源
连接条件的优化
遵循Where条件优化的建议

5.Select

能不能用函数
能不能用子查询
不用Select *
在查询中不要使用select *,检索不必要的列带来额外的系统开销

6.存储过程

合理使用临时表

  • 避免频繁创建和删除临时表,会影响数据库性能
  • 存储过程中某个复杂查询反复出现时, 可以把此查询结果先存入临时表, 提高性能
  • 在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定
    禁用游标,慎用循环
  • 禁止使用游标,游标效率低,编写复杂,用游标不如用循环
  • 然而当你需要使用循环的时候,你要考虑清楚有没有办法不使用循环而达到效果,如果一定要用,请务必考虑尽量减少循环的数据量
  • 发挥数据库的优化,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效

7.其他SQL优化

  • 控制嵌套调用的层数:存储过程嵌套,视图嵌套
  • 尽量避免大事务操作,提高系统并发能力。当使用约束和触发器都能完成同样的功能时,优先考虑使用约束。
  • 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理
  • Union和Union All :
    UNION 因为会将各查询子集的记录做比较,故比起UNION ALL ,通常速度都会慢上许多。一般来说,如果使用UNION ALL能满足要求的话,务必使用UNION ALL。还有一种情况大家可能会忽略掉,就是虽然要求几个子集的并集需要过滤掉重复记录,但由于脚本的特殊性,不可能存在重复记录,这时便应该使用UNION ALL,如xx模块的某个查询程序就曾经存在这种情况,见,由于语句的特殊性,在这个脚本中几个子集的记录绝对不可能重复,故可以改用UNION ALL)

8.堵塞与死锁

数据库阻塞
第一个连接占有资源没有释放,而第二个连接需要获取这个资源。如果第一个连接没有提交或者回滚,第二个连接会一直等待下去,直到第一个连接释放该资源为止。
长期堵塞严重影响系统体验,所以对数据库操作要及时地提交或者回滚
数据库死锁
第一个连接占有资源没有释放,准备获取第二个连接所占用的资源,而第二个连接占有资源没有释放, 准备获取第一个连接所占用的资源。这种互相占有对方需要获取的资源的现象叫做死锁。对于死锁,数据库处理方法:牺牲一个
死锁严重影响系统体验, 发现死锁脚本, 结合业务优化脚本
在这里插入图片描述

9.其他数据库性能优化

分库分表
读写分离: 高可用,订阅与发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/186540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

海康摄像头Linux开发

官方sdk下载 https://open.hikvision.com 点击下载就行了 Ubuntu摄像头抓拍测试 我们使用Linux64 纯净版测试 接好海康摄像头&#xff0c;通电&#xff0c;并设置号ip和用户名、密码。如果有现成的&#xff0c;可以去查一下就知道了 先把设备下载的文件解压并放到Ubuntu下面…

redis的渐进式rehash机制

简述 在redis的字典&#xff08;dict.h&#xff09;实现中&#xff0c;当哈希表保存的键值对太多或者太少时&#xff0c;会触发扩展/收缩&#xff1b; 触发收缩&#xff1a;负载因子小于 0.1触发扩展&#xff1a;以下任一条件符合即可 服务器目前没有在执行 BGSAVE 命令或者 …

k8s核心资源

一、NameSpace对资源进行隔离&#xff0c;比如开发环境和测试环境等。命令# 查看所有命名空间的资源 kubectl get pod -A # 查看单独某个命名空间下的资源 kubectl get pod -n <空间名称> # 查看所有命名空间 kubectl get ns # 创建命名空间 kubectl create ns <空间名…

SpringAMQP

SpringAMQP是基于RabbitMQ封装的一套模板&#xff0c;并且还利用SpringBoot对其实现了自动装配&#xff0c;使用起来非常方便。 SpringAmqp的官方地址&#xff1a;Spring AMQP SpringAMQP提供了三个功能&#xff1a; 自动声明队列、交换机及其绑定关系&#xff08;RabbitAdmin&…

Hive自定义UDF函数及使用

目录 一、UDF概述 二、编写自定义UDF 1.创建项目 2.pom.xml文件添加依赖 3.编写工具类及自定义UDF类 4.打包 5.测试 jar 6.上传至服务器、HDFS并给jar包赋权 7.添加到hive类路径并创建临时函数 8.使用测试&#xff1a; 9.临时函数、永久函数 一、UDF概述 UDF全称&…

面试项目经验相关技巧

前言 面试问项目经验主要是想了解所做项目用到的技术&#xff0c;以及自己在项目中扮演的角色。 一、秒杀系统 秒杀系统往往不是咱的项目经验&#xff0c;但是面试可能会问&#xff0c;在说自己项目经验的时候也可以往秒杀和高并发上面带。 可能遇到的问题 高并发 一般就是…

阿里云KMS创建应用接入点

1.进入KMS控制台https://kms.console.aliyun.com/cn-beijing/applicationAP/list2.应用管理->创建应用接入点应用接入点可以想象成一个入口。入口打开的时候&#xff0c;运行在你服务器中的代码&#xff08;KMS客户端&#xff09;才可以与阿里云的KMS实例通讯。2.1设置入口名…

【软件测试】离开“浪浪山“测试人迎来的春天......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 这几年因为疫情、经…

Activiti7工作环境搭建_创建基础工程自动创建Activiti数据库表---工作流工作笔记004

然后我们开始来搭建activiti的环境 首先给idea安装activiti插件,从插件里搜索 actiBPM注意,这个直接在idea中搜索可能搜索不到,因为太旧了这个工具,新的idea已经不支持,需要手动去actiBpm 官网下载以后手动安装 下载就可以了 下载以后点击齿轮,然后选择从硬盘安装 选择下载好的…

注册公司认缴vs实缴,选择哪一个更好?

前言 上一篇说了在创业的时候先进行选择公司类型&#xff0c;然后在公司注册过程中都需要登记公司的注册资本&#xff0c;会涉及注册资金这一点&#xff0c;而现在有认缴制和实缴制&#xff0c;到底选择哪一个更好呢&#xff1f; 在选择之前&#xff0c;先来和大家分享下认缴制…

PyG-节点分类+链接预测+异常检测示例

引言图神经网络(Graph Neural Networks)是一种针对图结构数据(如社交图、网络安全网络或分子表示)设计的机器学习算法。它在过去几年里发展迅速&#xff0c;被用于许多不同的应用程序。在这篇文章中我们将回顾GNN的基础知识&#xff0c;然后使用Pytorch Geometric解决一些常见的…

idea本地debug调试DATAX插件运行

datax官方github地址&#xff1a;GitHub - alibaba/DataX: DataX是阿里云DataWorks数据集成的开源版本。 接触datax是看重他的数据采集功能和可以扩展插件的功能&#xff0c;根据官方说明&#xff0c;DATAX是以python来调用插件的运行json配置&#xff0c;但对于二次开发插件的…

nacos权限区分

背景 nacos的默认是不进行分配权限的&#xff0c;那么这样就带来了一个问题&#xff0c;如果多项目共同使用一个nacos&#xff0c;可以带了一个情况是开发人员误操作&#xff0c;把其他项目的nacos配置文件更改或者删除。那么如何解决这个问题呢&#xff1f;就是把nacos进行分…

网络知识详解之:网络攻击与安全防护

网络知识详解之&#xff1a;网络攻击与安全防护 计算机网络相关知识体系详解 网络知识详解之&#xff1a;TCP连接原理详解网络知识详解之&#xff1a;HTTP协议基础网络知识详解之&#xff1a;HTTPS通信原理剖析&#xff08;对称、非对称加密、数字签名、数字证书&#xff09;…

Kotlin 1.8.0 现已发布,有那些新特性?

文章目录**如何安装 Kotlin 1.8.0****如果您遇到任何问题****更多文章和视频**结语Kotlin 1.8.0 版本现已发布&#xff0c;以下是其部分最大亮点&#xff1a; JVM 的新实验性功能&#xff1a;递归复制或删除目录内容提升了 kotlin-reflect 性能新的-Xdebug编译器选项&#xff…

PCB铺铜技巧如何铺铜经验总结

&#x1f3e1;《总目录》 目录1&#xff0c; 什么是铺铜2&#xff0c;铺铜的好处3&#xff0c;如何铺铜4&#xff0c;铺铜的经验原则5&#xff0c;铺铜的注意事项1&#xff0c; 什么是铺铜 铺铜是指在PCB电气层添加整块的铜皮&#xff1b;铺铜包括电源层铺铜&#xff0c;地层铺…

openofdm03:Frequency Offset Correction

载波频率偏移&#xff08;Carrier Frequency Offset&#xff0c;CFO&#xff09;&#xff1a;发射机和接收机本振频率之差&#xff0c;会造成接收到的I/Q采样值的相位旋转。This symptom of this offset is a phase rotation of incoming I/Q samples (time domain). The CFO c…

基于语义分割实现人脸图像的皱纹检测定位与分割

前言 人脸皱纹主要区分有额纹、川字纹、眼下纹、法令纹、嘴角纹&#xff0c;眼角纹等&#xff0c;在美颜相机&#xff0c;智能医美等于应用领域里&#xff0c;需要对人脸皱纹进行检测、定位、分割&#xff0c;测量等。 传统图像算法的皱纹检测 1.传统算法的皱纹检测可参考《…

仿京东PC网页商品详情的放大镜效果(原理+代码)

实现效果 黑色只不过是转gif出问题而已 准备工作 1. 访问该网址&#xff0c;理解我们要弄的放大镜效果&#xff0c;鼠标经过商品图片&#xff0c;显示一个黄色的放大选区&#xff0c;右边显示该选区的大图。 2. 获取商品图片和商品大图 【摩托罗拉moto X30 Pro】摩托罗拉mot…

protocol-buffers 基础(一)

protocol-buffers 官网 Github 一、概述 协议缓冲区&#xff08;protocol-buffers&#xff09;是一种与语言无关、与平台无关的可扩展机制&#xff0c;用于序列化结构化数据。 协议缓冲区提供了一种与语言无关、与平台无关、可扩展的机制&#xff0c;用于以向前兼容和向后兼…