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. Qt疑难问题-模态窗口父类被析构

    最近遇到一个朋友,问了我一个刁钻的问题,当你模态弹出一个窗体时,后台把这个窗体的父类给析构了,这个时候会出现什么样的情况? 听到问题后我真是一脸懵逼呀!从来没有这么写过代码. 随后写了一个简单的测试d ...

  2. Winform去掉标题栏后移动窗体

    第一步:声明全局变量->  private Point _HoverTreePosition; 第二步: #region 隐藏标题栏后移动窗口 private void Form_HoverTr ...

  3. pt-table-sync 配合pt-table-checksum 修复主从不一致

    pt-table-sync 配合pt-table-checksum 修复主从不一致. 先执行下面这条语句,打印出要执行的命令,确认无误后再将  --print  改为  --execute 执行.注意 ...

  4. 2020Pycharm安装教程!最新2020pycharm安装!如何安装Pycharm2020版本!如何安装Pycharm!如何安装2020Pycharm!2020Pycharm永久激活!

    本教程仅用作个人学习,请勿用于商业获利,造成后果自负!!! Pycharm安装 在这插一个小话题哈,Pycharm只是一个编译器,并不能代替Python,如果要使用Python,还是需要安装Pytho ...

  5. Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取

    在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...

  6. 10 大 python 库

    TensorFlow Scikit-Learn Numpy Keras PyTorch LightGBM Eli5 SciPy Theano Pandas 简介 python 是最流行和使用最广泛的编 ...

  7. webservice传输文件的三种方式

    1, 在接口中不定义,直接以附件形式传输. 2, 在接口参数中定义byte[]类型,文件在xml中以base64编码传输. 3, 在接口参数中定义DataHandler类型,然后使用MTOM形式来进行 ...

  8. 『王霸之路』从0.1到2.0一文看尽TensorFlow奋斗史

    ​ 0 序篇 2015年11月,Google正式发布了Tensorflow的白皮书并开源TensorFlow 0.1 版本. 2017年02月,Tensorflow正式发布了1.0.0版本,同时也标志 ...

  9. 利用百度云接口实现车牌识别·python

    一个小需求---实现车牌识别. 目前有两个想法 1. 调云在线的接口或者使用SDK做开发(配置环境和变异第三方库麻烦,当然使用python可以避免这些问题) 2. 自己实现车牌识别算法(复杂) 一开始 ...

  10. 死磕 java线程系列之创建线程的8种方式

    (手机横屏看源码更方便) 问题 (1)创建线程有哪几种方式? (2)它们分别有什么运用场景? 简介 创建线程,是多线程编程中最基本的操作,彤哥总结了一下,大概有8种创建线程的方式,你知道吗? 继承Th ...