sql优化提速整理

简介: 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 Value 1 and 3

  7、查询时避免使用like '%待查询关键字%' 查询

  8、在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,

  否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致

  9、能够用关联查询的不要用exists

  10、避免频繁创建和删除临时表,以减少系统表资源的消耗。

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


分区存储


  当单表的数量达到一定量时,为了提高查询效率,数据表分区存储也是一个不错的优化方案。

  分区呢就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,通过提高减少文件大小,提高IO处理效率,间接的提高查询效率

  分区存储,只是在数据存储上采用分区,但是在表现上还是一张表。

  表分区有以下优点:

    1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。

    2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;

    3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;

    4、均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。

  缺点:

  分区表相关:已经存在的表没有方法可以直接转化为分区表


分库分表


  分库分表其实原理也是将一个大表拆分不同的小表,在拆分上有两种拆分方式:

  横向拆分:主要针对一个表的字段比较多,可以根据字段的查询频率、更新频率进行分割存储,可以理解为表扩展

  纵向拆分:纵向拆分主要是根据数据量,将数据存储在不同的表,常用的拆分方式有:按照时间、按照哈希等等

  分库分表和分区存储两者看上去是有点矛盾,实际上两者的出发点不一样。分区:是降低大单表数据分区存储,分库分表:直接将单表拆分为多表

  同时分库分表不仅仅会增加数据维护难度,同时也会需要投入大量的开发工作,所以分库分表一般是要系统有一定的规模,公司有一定的资源支持

  分库分表两种可以配合使用,比如在分表后,还可以对表进行分区存储。


总结


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

相关文章
|
10天前
|
SQL 存储 关系型数据库
不懂索引,简历上都不敢写自己熟悉SQL优化
大家好,我是考哥。今天给大家带来MySQL索引相关核心知识。对MySQL索引的理解甚至比你掌握还重要,索引是优化SQL的前提和基础,我们一步步来先打好地基。当MySQL表数据量不大时,缺少索引对查询性能的影响都不会太大,可能都是0.0几秒;但当表数据量逐日递增时,建立一个合适且优雅的索引就至关重要了。
798 1
不懂索引,简历上都不敢写自己熟悉SQL优化
|
7天前
|
SQL 分布式计算 大数据
MaxCompute产品使用问题之如果oss文件过大,如何在不调整oss源文件大小的情况下优化查询sql
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
14天前
|
SQL 关系型数据库 MySQL
SQL优化方法有哪些?
【6月更文挑战第16天】SQL优化方法有哪些?
220 5
|
14天前
|
SQL 数据处理 数据库
如何进行SQL查询优化?
【6月更文挑战第16天】如何进行SQL查询优化?
363 3
|
21天前
|
SQL 缓存 监控
sql anywhere 数据库优化
SQL Anywhere数据库优化涉及索引、查询、配置、硬件、维护和应用程序多方面。关键策略包括:确保索引有效且定期优化,使用EXPLAIN计划优化查询,调整数据库缓存设置,升级硬件,定期备份,优化SQL语句并减少数据库访问。实时监控性能并据此调优,但需依据具体应用场景和版本进行适配测试。
|
24天前
|
存储 SQL 关系型数据库
MySQL数据库——SQL优化(1/3)-介绍、插入数据、主键优化
MySQL数据库——SQL优化(1/3)-介绍、插入数据、主键优化
236 1
|
4天前
|
SQL 存储 关系型数据库
Mysql-事务-锁-索引-sql优化-隔离级别
Mysql-事务-锁-索引-sql优化-隔离级别
|
1月前
|
SQL 监控 数据库
sql anywhere 数据库优化
\ Anywhere\对于任何数据库系统,优化都是持续的过程,旨在提高查询性能、减少资源消耗并确保数据的完整性和安全性。以下是一些建议,帮助您优化 SQL Anywhere 数据库: 1. **
58 5
|
1月前
|
SQL 监控 关系型数据库
【PolarDB开源】PolarDB SQL优化实践:提升查询效率与资源利用
【5月更文挑战第24天】PolarDB是高性能的云原生数据库,强调SQL查询优化以提升性能。本文分享了其SQL优化策略,包括查询分析、索引优化、查询重写、批量操作和并行查询,以及性能监控与调优方法。通过这些措施,可以减少响应时间、提高并发处理能力和降低成本。文中还提供了相关示例代码,展示如何分析查询和创建索引,帮助用户实现更高效的数据库管理。
204 1
|
17天前
|
SQL 存储 关系型数据库
慢查询优化方案-SQL篇【JavaPub版】
慢查询优化方案-SQL篇【JavaPub版】
123 0