sql优化提速整理

场景描述

在我们实际开发中,随着业务的不断增加,数据量也在不断的攀升,这样就离不开一个问题:数据查询效率优化
根据自己的以往实际项目工作经验和学习所知,现在对SQL查询优化做一个简单的梳理总结,总结的不好之处,望多多指点交流学习
主要通过以下几个点来进行总结分析:索引、语句本身、分区存储、分库分表

索引

  在实际工作中,sql优化第一想到的应该就是索引,因为添加索引能够很直观的提升查询效率,但是在添加索引的时也不是越多多好,下面简单总结一下索引的实际使用

  索引简介

  关于索引的定义,在此不详细说明,网上的资料很多。索引简单的理解就是数据的目录,就好比一个字典的目录,其目的是提高查询效率

  索引分类

   SQL索引根据存储关系,分为两类:聚合索引和非聚合索引

  聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致,聚合索引的索引排序与表记录的排序是一致的,非聚合索引正好相反。
  在一个表中,只会存在一个聚合索引,主键默认就是聚合索引,聚合索引的关键词为:clustered
  创建聚合索引的SQL语句:

  ---- 根据数据表的字段1、字段2创建一个组合的聚合索引
  use 库名
  create clustered index 索引名称 on 表名(字段1,字段2)

  SQL索引根据使用关系,分为四类:主键索引、唯一索引、普通索引(组合索引)、全文索引
  主键索引:
  表的主键自动为主键索引,每条数据的唯一标识,一个表只有一个主键索引
  唯一索引:
  唯一索引也是确保数据的唯一性,一个表可以多有多个唯一索引,这也是和主键索引的区别所在
  创建唯一索引sql语句:  

create UNIQUE index 索引名称 on 表名(字段1,字段2)

  普通索引:
  普通索引可以对任意字段或者多个字段添加索引

  

----创建普通索引sql语句:
  create index 索引名称 on 表名(字段1,字段2) 

  索引创建技巧

  

动作描述

使用聚集索引 

 使用非聚集索引

外键列

主键列

列经常被分组排序(order by)

返回某范围内的数据

不应

小数目的不同值

不应

大数目的不同值

不应

频繁更新的列

不应

频繁修改索引列

不应

一个或极少不同值

不应

不应

  建立索引的原则

  • 定义主键的数据列一定要建立索引。
  • 定义有外键的数据列一定要建立索引。
  • 对于经常查询的数据列最好建立索引。
  • 对于需要在指定范围内的快速或频繁查询的数据列;
  • 经常用在WHERE子句中的数据列。
  • 经常出现在关键字order by、group by、distinct后面的字段,建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则索引不会被使用。
  • 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。
  • 对于定义为text、image和bit的数据类型的列不要建立索引。
  • 对于经常存取的列避免建立索引
  • 限制表上的索引数目。对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。索引虽说提高了访问速度,但太多索引会影响数据的更新操作。
  • 对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用,因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。

  索引碎片化处理(重构索引)

  关于索引的定义,在此不详细说明,网上的资料很多。索引简单的理解就是数据的目录,就好比一个字典的目录,其目的是提高查询效率

  索引简介

  在实际开发中,有时候会发现新增了索引,但是效率还是没有明显提升,这时候需要考虑是否由于数据的更新编辑产生了索引碎片化,并处理

  如果检查是否有索引碎片:

---- 检查一个表索引碎片化
  use 库名
DBCC ShowContig(待查询的表) ---- 执行结果实例:

DBCC SHOWCONTIG 正在扫描 'SYS_Confige' 表...
表: 'SYS_Confige' (37575172);索引 ID: 1,数据库 ID: 7
已执行 TABLE 级别的扫描。
- 扫描页数................................: 7885
- 扫描区数..............................: 986
- 区切换次数..............................: 985
- 每个区的平均页数........................: 8.0
- 扫描密度 [最佳计数:实际计数].......: 100.00% [986:986]
- 逻辑扫描碎片 ..................: 0.01%
- 区扫描碎片 ..................: 1.12%
- 每页的平均可用字节数.....................: 23.0
- 平均页密度(满).....................: 99.72%
DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

----数据结构分析:处理

  Logical Scan Fragmentation-逻辑扫描碎片:无序页的百分比。该百分比应该在0%到10%之间,高了则说明有外部碎片。

  解决方式:
  解决方式有两种方式:整理索引碎片、重建索引,在实际操过程中建议采用:重建索引。
  重建索引的SQL语句:
  use 库名
  DBCC DBREINDEX(待重建索引的表名称)

查询语句优化

  在处理好索引后,接下来就是分析查询语句,查询语句可以借助专业的分析工具来分析,一个好的语句和不好的语句也会很影响效率,现在简单总结一下在查询语句的优化方向:

  1、查询字段禁止出现 selete *

2、where 及 order by 涉及的列上建立索引。

  3、where避免出现非空判断:比如:select from table where num is null
    此时可以给num赋一个默认值0,语句修改为:select from table where num=0

  4、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描

  5、应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
    -----查询value值为1 或者 4 的数据集合
    select Id from SYS_Confige where Value=1 or Value=4

    ---- 可以这样查询:
    select * from SYS_Confige where Value=1
    union all
    select * from SYS_Confige where Value=4
  6、in 和 not in 也要慎用,否则会导致全表扫描,如:
    select id from SYS_Configet where Value in(1,2,3)
    对于连续的数值,能用 between 就不要用 in 了:
    select id from SYS_Configet where num between  Value 1 and 3
  7、查询时避免使用like '%待查询关键字%' 查询
  8、在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,
  否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致
  9、能够用关联查询的不要用exists
  10、避免频繁创建和删除临时表,以减少系统表资源的消耗。

  11、尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理

分区存储

  当单表的数量达到一定量时,为了提高查询效率,数据表分区存储也是一个不错的优化方案。
  分区呢就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,通过提高减少文件大小,提高IO处理效率,间接的提高查询效率
  分区存储,只是在数据存储上采用分区,但是在表现上还是一张表。

  表分区有以下优点:
    1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
    2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
    3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
    4、均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。
  缺点:
  分区表相关:已经存在的表没有方法可以直接转化为分区表

分库分表

  分库分表其实原理也是将一个大表拆分不同的小表,在拆分上有两种拆分方式:
  横向拆分:主要针对一个表的字段比较多,可以根据字段的查询频率、更新频率进行分割存储,可以理解为表扩展
  纵向拆分:纵向拆分主要是根据数据量,将数据存储在不同的表,常用的拆分方式有:按照时间、按照哈希等等
  分库分表和分区存储两者看上去是有点矛盾,实际上两者的出发点不一样。分区:是降低大单表数据分区存储,分库分表:直接将单表拆分为多表

  同时分库分表不仅仅会增加数据维护难度,同时也会需要投入大量的开发工作,所以分库分表一般是要系统有一定的规模,公司有一定的资源支持
  分库分表两种可以配合使用,比如在分表后,还可以对表进行分区存储。

总结

 在数据优化过程中,索引是第一出发点,语句优化必不可少,分区、分库、分表也得考虑。

sql优化提速整理的更多相关文章

  1. sql优化点整理

    此文是我最早开始sql优化至今整理的小知识点和经常遇到的问题,弄懂这些对优化大型的sql会有不少帮助 ---------------------------------使用了多余的外连接------- ...

  2. Oracle SQL 优化原则(实用篇)

    由于SQL优化优化起来比较复杂,并且还受环境限制,在开发过程中,写SQL必须遵循以下几点原则: 1.Oracle 采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他Where ...

  3. oracle sql优化

    整理一下网上所看到sql优化方法 1.使用大写字母书写sql,因为oracle解释器会先将sql语句转换成大写后再解释 2    减少访问数据库的次数,多数情况下一条sql可以达到目的的,就不要使用多 ...

  4. C# SQL优化 及 Linq 分页

    每次写博客,第一句话都是这样的:程序员很苦逼,除了会写程序,还得会写博客!当然,希望将来的一天,某位老板看到此博客,给你的程序员职工加点薪资吧!因为程序员的世界除了苦逼就是沉默.我眼中的程序员大多都不 ...

  5. 数据库SQL优化大总结之百万级数据库优化方案

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...

  6. (转)数据库SQL优化大总结之 百万级数据库优化方案

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...

  7. SQL优化的四个方面,缓存,表结构,索引,SQL语句

    一,缓存 数据库属于 IO 密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在毫秒级别,二者相差3个数量级.所 ...

  8. SQL优化(Oracle)

    (转)SQL优化原则 一.问题的提出 在应用系统开发初期.因为开发数据库数据比較少.对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,可是假设将应用系统提交实际应用后,随着数 ...

  9. 深入浅出Hive企业级架构优化、Hive Sql优化、压缩和分布式缓存(企业Hadoop应用核心产品)

    一.本课程是怎么样的一门课程(全面介绍)    1.1.课程的背景       作为企业Hadoop应用的核心产品,Hive承载着FaceBook.淘宝等大佬 95%以上的离线统计,很多企业里的离线统 ...

随机推荐

  1. abp(net core)+easyui+efcore实现仓储管理系统——EasyUI之货物管理一 (十九)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...

  2. Decorator:从原理到实践

    前言 原文链接:Nealyang/personalBlog ES6 已经不必在过多介绍,在 ES6 之前,装饰器可能并没有那么重要,因为你只需要加一层 wrapper 就好了,但是现在,由于语法糖 c ...

  3. php根据经纬度排序,根据经纬度筛选距离段

    SQL 语句:select location.* from (select *,round(6378.138*2*asin(sqrt(pow(sin( (36.668530*pi()/180-px_l ...

  4. 采用redis生成唯一且随机的订单号

    项目描述 最近做的一个项目有这么一个需求:需要生成一个唯一的11位的就餐码(类似于订单号的概念),就餐码的规则是:一共是11位的数字,前面6位是日期比如2019年07月20就是190720,后面五位是 ...

  5. Django REST Framework序列化器

    Django序列化和json模块的序列化 从数据库中取出数据后,虽然不能直接将queryset和model对象以及datetime类型序列化,但都可以将其转化成可以序列化的类型,再序列化. 功能需求都 ...

  6. Scala Basis

    基础 Scala 中数据类型也是 class 7 种数值类型: Byte, Char, Short, Int, Long, Float, and Double Boolean 类型 原始类型与 cla ...

  7. Sentinel Core流程分析

     上次介绍了Sentinel的基本概念,并在文章的最后介绍了基本的用法.这次将对用法中的主要流程和实现做说明,该部分主要涉及到源码中的sentinel-core模块. 1.token获取   如上为t ...

  8. Spring Boot Thymeleaf 实现国际化

    开发传统Java WEB工程时,我们可以使用JSP页面模板语言,但是在SpringBoot中已经不推荐使用了.SpringBoot支持如下页面模板语言 Thymeleaf FreeMarker Vel ...

  9. 基于 HTML5 和 WebGL 的地铁站 3D 可视化系统

    前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...

  10. 【SQL server基础】获取当前时间并固定格式

    Select CONVERT(varchar(), GETDATE(), ): // Select CONVERT(varchar(), GETDATE(), ): Select CONVERT(va ...