数据库大数据量的优化方案
在系统开发的初期以及使用的初期,一般不会太过于在意数据库的设计以及sql语句的优化,这就会导致系统有可能在日积月累的海量数据下越来越慢直至崩溃,所以以后在系统 数据库设计之初完备的数据库模型的设计是必须的。
优化数据库方案
对于数据库的的优化此处给出三种优化方案:
- 1.优化现有mysql数据库
优点:不影响现有业务,源程序不需要修改代码,成本最低
缺点:有优化瓶颈,数据量过亿就无法继续支撑相应的业务 - 2.升级数据库类型,换一种100%兼容mysql的数据库
优点:不影响现有业务,源程序不需要修改代码,你几乎不需要做任何操作就能提升数据库性能
缺点:多花钱 - 3.一步到位,大数据解决方案,更换newsql/nosql数据库
优点:扩展性强,成本低,没有数据容量瓶颈
缺点:需要修改源程序代码
1.方案一:优化现有数据库
- 1.数据库设计和表创建时就要考虑性能
- 2.sql的编写需要注意优化
- 3.分区
- 4.分表
- 5.分库
1.1 数据库设计和表创建时就要考虑性能
mysql数据库本身高度灵活,造成性能不足,严重依赖开发人员能力。也就是说开发人员能力高,则mysql性能高。这也是众多关系型数据库的通病
所以我们在设计表时应当注意:
- 1.表字段避免null值出现,null值很难查询优化且占用额外的索引空间,推荐默认数字0代替null。
- 2.尽量使用INT而非BIGINT,如果非负则加上UNSIGNED(这样数值容量会扩大一倍),当然能使用TINYINT、SMALLINT、MEDIUM_INT更好。
- 3.使用枚举或整数代替字符串类型
- 4.尽量使用TIMESTAMP而非DATETIME
- 5.单表不要有太多字段,建议在20以内
- 6.用整型来存IP
- 7.数据行的长度不要超过8020字节,如果超过这个长度的话在物理页中这条数据会占用两行从而造成存储碎片,降低查询效率。
- 8.能够用数字类型的字段尽量选择数字类型而不用字符串类型的(电话号码),这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
- 9.对于不可变字符类型char和可变字符类型varchar 都是8000字节,char查询快,但是耗存储空间,varchar查询相对慢一些但是节省存储空间。在设计字段的时候可以灵活选择,例如用户名、密码等长度变化不大的字段可以选择CHAR,对于评论等长度变化大的字段可以选择VARCHAR。
- 10.字段的长度在最大限度的满足可能的需要的前提下,应该尽可能的设得短一些,这样可以提高查询的效率,而且在建立索引的时候也可以减少资源的消耗。
1.2 查询优化
- 1.保证在实现功能的基础上,尽量减少对数据库的访问次数;
- 2.通过搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;
- 能够分开的操作尽量分开处理,提高每次的响应速度;
- 3.在数据窗口使用SQL时,尽量把使用的索引放在选择的首列;
- 4.算法的结构尽量简单;
- 5.在查询时,不要过多地使用通配符如SELECT * FROM T1语句,要用到几列就选择几列
- 6.在可能的情况下尽量限制尽量结果集行数
- 7.在查询时,不要过多地使用通配符如SELECT * FROM T1语句,要用到几列就选择几列;
在没有建索引的情况下,数据库查找某一条数据,就必须进行全表扫描了,对所有数据进行一次遍历,查找出符合条件的记录。在数据量比较小的情况下,也许看不出明显的差别,但是当数据量大的情况下,这种情况就是极为糟糕的了。 - 8.尽量使语句符合查询优化器的规则避免全表扫描而使用索引查询
下面我重点讲解一下第8点
比如select * from table1 where name=‘zhangsan’ and tID > 10000
和执行:
select * from table1 where tID > 10000 and name=‘zhangsan’
一些人不知道以上两条语句的执行效率是否一样,因为如果简单的从语句先后上看,这两个语句的确是不一样,如果tID是一个聚合索引,那么后一句仅仅从表的 10000条以后的记录中查找就行了;而前一句则要先从全表中查找看有几个name='zhangsan’的,而后再根据限制条件条件tID> 10000来提出查询结果。但是实际上在实际查询时SQL SERVER中有一个“查询分析优化器”,它可以计算出where子句中的搜索条件并确定哪个索引能缩小表扫描的搜索空间,也就是说,它能实现自动优化。虽然查询优化器可以根据where子句自动的进行查询优化,但有时查询优化器就会不按照您的本意进行快速查询。
在查询分析阶段,查询优化器查看查询的每个阶段并决定限制需要扫描的数据量是否有用。如果一个阶段可以被用作一个扫描参数(SARG),那么就称之为可优化的,并且可以利用索引快速获得所需数据。
SARG的定义:用于限制搜索的一个操作,因为它通常是指一个特定的匹配,一个值的范围内的匹配或者两个以上条件的AND连接。
列名可以出现在操作符的一边,而常数或变量出现在操作符的另一边。如:
Name=’张三’
价格>5000
5000<价格
Name=’张三’ and 价格>5000
如果一个表达式不能满足SARG的形式,那它就无法限制搜索的范围了,也就是SQL SERVER必须对每一行都判断它是否满足WHERE子句中的所有条件。所以一个索引对于不满足SARG形式的表达式来说是无用的。
所以,优化查询最重要的就是,尽量使语句符合查询优化器的规则避免全表扫描而使用索引查询。
接下来通过查询优化规则接续看看在具体编写sql语句的时候应该需要注意哪些内容 :
查询语句中对于where的优化:
9.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
如:select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=010.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。
11.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描
如:select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=2012.in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据。
如:select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了
select id from t where num between 1 and 313.尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。
见如下例子:
SELECT * FROM T1 WHERE NAME LIKE ‘%L%’
SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’
SELECT * FROM T1 WHERE NAME LIKE ‘L%’
即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。14.必要时强制查询优化器使用某个索引,如在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。
如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num15.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。
如:- SELECT * FROM T1 WHERE F1/2=100
应改为:SELECT * FROM T1 WHERE F1=100*2 - SELECT * FROM RECORD WHERE SUBSTRING(CARD_NO,1,4)=’5378’
应改为:SELECT * FROM RECORD WHERE CARD_NO LIKE ‘5378%’ - SELECT member_number, first_name, last_name FROM members WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21
应改为:SELECT member_number, first_name, last_name FROM members WHERE dateofbirth < DATEADD(yy,-21,GETDATE())
即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
- SELECT * FROM T1 WHERE F1/2=100
16.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
17.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
18.很多时候用 exists是一个好的选择:
elect num from a where num in(select num from b)
用下面的语句替换:select num from a where exists(select 1 from b where num=a.num)
数据库大数据量的优化方案相关推荐
- spring Batch实现数据库大数据量读写
spring Batch实现数据库大数据量读写 博客分类: spring springBatchquartz定时调度批处理 1. data-source-context.xml Xml代码 &l ...
- 数据库大数据量、高并发、高可用解决方案!
数据库性能瓶颈 对于一些互联网项目来说,企业为节省成本,一般会考虑将所有的数据都存储在一个数据库中,这个时候我们只需要考虑数据库优化.SQL优化.数据缓存.限流,消息队列.服务器性能等问题. 阿里巴巴 ...
- EasyExcel 低内存导出大数据量的Excel方案探索 50万行 50列 (附:实现代码)
文章目录 1.前言 2.准备工作 3.导出测试 3.1.单次查询.全量导出 3.2. 多次查询,多个文件,单次写入 3.3.多次查询,多个文件,多次写入 3.4.多线程导出探索 3.5.文件打包成ZI ...
- 数据库大量数据操作中事务优化方案
1.业务场景: 1)短时间内向数据库中插入大量数据: 2)大批量数据修改操作: 3)批量删除数据. 2.两个弊端方案 1.处理完毕后统一提交数据库: 2.每操作完一条记录,就提交更新. 3.优化方案: ...
- 大数据量性能优化之分页查询
刷帖子翻页需要分页查询,搜索商品也需分页查询.当遇到上千万.上亿数据量,怎么快速拉取全量数据呢? 比如: 大商家拉取每月千万级别的订单数量到自己独立的ISV做财务统计 拥有百万千万粉丝的大v,给全部粉 ...
- c# 大数据量比较时-方案
1.当面临千万条数据量的比较时,从技术的角度来说应该用泛型键值(c#键值由于用了散列算法速度很快).例如前几天我需要查的是 航空公司.出发.到达.返点可以将 航空公司-出发-到达做一个键,返点作为值. ...
- sql 大数据量插入优化
在做一IOS项目时,因为要动态根据文件导入创建数据库,刚开始的时候因为使用动态查询的方式,就是每次插入数据之前查询当前数据是否已经存在,这样的效率极低.6w条纪录3个关联表,使用了30-50分钟的样子 ...
- excel导入sqlserver数据库大数据量,可每秒控制数量
数据库代码 USE [Test] GO /****** Object: Table [dbo].[Table_1] Script Date: 11/07/2017 17:27:29 ***** ...
- 3DGIS第二章 大数据量场景加速绘制基本原理与方法
对于仅有几百个多边形和几十兆的低分辨率纹理简单场景,在现阶段一般配置的计算机上也很容易达到实时仿真的目标.然而,随着场景规模的增大,大规模虚拟场景中往往包含上万个多边形,甚至多达几百万个多边形和几百兆 ...
- 大数据量场景加速绘制基本原理与方法
对于仅有几百个多边形和几十兆的低分辨率纹理简单场景,在现阶段一般配置的计算机上也很容易达到实时仿真的目标.然而,随着场景规模的增大,大规模虚拟场景中往往包含上万个多边形,甚至多达几百万个多边形和几百兆 ...
最新文章
- wp7 手机归属地查询
- 软件测试工具按用途分分为哪几类,以测试的形态分软件测试可以分为哪几类?...
- 序列模型简介——RNN, Bidirectional RNN, LSTM, GRU
- javescript的内置对象
- 在PHP代码中处理JSON 格式的字符串的两种方法:
- 根据压缩后的行列数和sourcemap反向定位源码
- http,tcp的长连接和短连接
- Xampp PHPStorm XDebug配置
- 谁有 CaliberRM.2005.Enterprise 版 或CaliberRM.2006 注册码?
- GBK汉字的索引方法
- matlab怎么取差分,差分进化算法原理与matlab实现
- optim优化器的使用
- 天大计算机研究生毕业工资,本科生VS研究生工资差距这么大?又一高校薪资排行曝光,看完扎心了……...
- 如何使用PDF Expert将文本添加到PDF?
- 青龙面板+傻妞sillyGirl+阿东自动登录全套保姆级一步到位教程(2021-10-09)
- 工业防腐漆的作用,你知道的有几个
- Java代码的.equest的空指针异常
- ajax实现留言板功能 -
- 康有为《公车上书》纯属虚构? - 转自《爱野史网》
- 木马 万能 删除法
热门文章
- (5)Redis主从同步原理及详细配置
- systemd(CentOS7)启动zookeeper
- 【Mybatis架构】Mapper映射文件中的#{}与${}
- web工程was部署
- 为RecyclerView打造通用Adapter
- javax.persistence.TransactionRequiredException: No transactional EntityManager available
- global.asax、global.asax.compiled、PrecompiledApp.config三者关系
- python的序列之列表
- 安装无线网卡后,显示网络电缆被拔出?
- C# ASP.NET里@的妙用