转载自:https://www.cnblogs.com/ShaYeBlog/p/10383644.html

大数据量的查询,不仅查询速度非常慢,而且还会导致数据库经常宕机(刚接到这个项目时候,数据库经常宕机o(╯□╰)o)。 那么,如何处理上亿级的数据量呢?如何从数据库经常宕机到上亿数据秒查?仅以此篇文章作为处理的总结。

数据背景:
下面是存放历史数据表的数据量,数据量确实很大,3亿多条。但这也仅仅是测试数据而已,因为客户端服务器上的数据可能远不止于此。

为什么说远不止于此呢?实际情况是这样的:

有一个实时数据表,THTF_TABLE_AI,以及历史数据表,THTF_TABLE_AI_HIS

实时数据表固定3万条数据(客户推送过来的数据),每2小时刷新一次,每刷新一次就往历史表中插入一次数据。

可以算一下,历史表中数据量的数据量:

3 x 12 x 30 = 1080万,也就是每个月存储1080条数据,1年就1亿多的数据量。这样大的数据量,导致查询速度慢,估计用户会气炸的…

解决方案:
第一步:分表

如果历史表中存储了很多年的数据,会造成严重的数据冗余。那如果将历史表分表存储,比如每年创建一个表,数据存储到对应的年表中,必定会减少很多数据量。(如果分成年表数据量还是过大,可以细分到月表,天表…)。

我们这里以创建年表为例,写一个创建年表的存储过程,利用PLSQL定时任务定时执行此存储过程(定时每年12月31号创建下一年的年表)。存储过程如下,定时任务查看此篇文章:PLSQL执行Oracle定时任务

CREATE OR REPLACE
PROCEDURE CREATE_YEAR_TABLE IS
/变量/
grantSql VARCHAR2(50);
yearStr VARCHAR2(4);
tableCount int(2);
createSql VARCHAR2(1000);
BEGIN
/权限/
grantSql := ‘grant create any table to thtf_taiyuan’;
EXECUTE IMMEDIATE grantSql;
/创建年表 注意create table 后边的空格/
SELECT TO_CHAR(SYSDATE, ‘yyyy’)+1 INTO yearStr FROM dual;
createSql := 'CREATE TABLE ’ || ‘THTF_TABLE_YEAR_’ || yearStr ||
‘( SHE_SHI_CODE VARCHAR2(100),
SHE_SHI_TYPE NUMBER DEFAULT 1,
FEN_GONG_SI VARCHAR2(100),
SHUI_HAO NUMBER(20,4) DEFAULT 0,
PRE_SHUI_HAO NUMBER(20,4) DEFAULT 0,
DIAN_HAO NUMBER(20,4) DEFAULT 0,
PRE_DIAN_HAO NUMBER(20,4) DEFAULT 0,
RE_HAO NUMBER(20,4) DEFAULT 0,
PRE_RE_HAO NUMBER(20,4) DEFAULT 0,
SHI_JIAN DATE DEFAULT SYSDATE,
STATE NUMBER DEFAULT 1 )’;
SELECT COUNT(1) INTO tableCount FROM user_tables WHERE table_name = CONCAT(‘THTF_TABLE_YEAR_’, yearStr);
IF tableCount = 0 THEN
EXECUTE IMMEDIATE createSql;
COMMIT;
END IF;
END CREATE_YEAR_TABLE;
第二步:分区

年表创建过后,查询就是查询年表中的数据,可是虽然分表了,但是年表中的数据量仍然很大,查询速度虽然有提升,但并不能满足用户的要求。便考虑到分表再分区,即将历史数据以不同的年表来存储,在年表中按月分区。

说道分区,要恶补一下了~

数据库分区:就是减少SQL操作的数据量,从而提升查询效率。表分区后,逻辑上仍然是一张表,只不过将表中的数据在物理上存放到多个表空间上。这样在查询数据时,会查询相应分区的数据,避免了全表扫描。

分区又分为水平分区、垂直分区。

水平分区:就是对行进行分区,举个例子来说,就是一个表中有1000万条数据,每100万条数据划一个分区,这样就将表中数据分到10个分区中去。水平分区要通过某个特定的属性列进行分区,比如我用的列就是Date时间。

垂直分区:通过对标垂直划分来减少表的宽度,从而提升查询效率。比如一个学生表中,有他相关的信息列,还有论文列以CLOB存储。这些以CLOB存储的论文并不会经常被访问到,这时候就要把这些不经常使用的CLOB划分到另一个分区,需要访问时再调用它。

总的来说,分区的主要目的还是避免了全表扫描,从而提升查询速度。

接下来在上面的存储过程的基础上,我们创建按月分区。

CREATE OR REPLACE
PROCEDURE CREATE_YEAR_TABLE IS
grantSql VARCHAR2(50);
yearStr VARCHAR2(4);
tableCount int(2);
createSql VARCHAR2(1000);
BEGIN
/权限/
grantSql := ‘grant create any table to thtf_taiyuan’;
EXECUTE IMMEDIATE grantSql;
/创建年表 注意create table 后边的空格/
SELECT TO_CHAR(SYSDATE, ‘yyyy’)+1 INTO yearStr FROM dual;
createSql := ‘CREATE TABLE ’ || ‘THTF_TABLE_YEAR_’ || yearStr ||
‘( SHE_SHI_CODE VARCHAR2(100),
SHE_SHI_TYPE NUMBER DEFAULT 1,
FEN_GONG_SI VARCHAR2(100),
SHUI_HAO NUMBER(20,4) DEFAULT 0,
PRE_SHUI_HAO NUMBER(20,4) DEFAULT 0,
DIAN_HAO NUMBER(20,4) DEFAULT 0,
PRE_DIAN_HAO NUMBER(20,4) DEFAULT 0,
RE_HAO NUMBER(20,4) DEFAULT 0,
PRE_RE_HAO NUMBER(20,4) DEFAULT 0,
SHI_JIAN DATE DEFAULT SYSDATE,
STATE NUMBER DEFAULT 1 )
/按月分区/
PARTITION BY RANGE(SHI_JIAN)
INTERVAL(NUMTOYMINTERVAL(1,’’’ || ‘MONTH’ || ‘’’))
( PARTITION PART1 VALUES LESS THAN(TO_DATE(’’’|| CONCAT(yearStr, ‘-11-01’) ||’’’,’’’|| ‘YYYY-MM-DD’ ||’’’)) )’;
SELECT COUNT(1) INTO tableCount FROM user_tables WHERE table_name = CONCAT(‘THTF_TABLE_YEAR_’, yearStr);
IF tableCount = 0 THEN
EXECUTE IMMEDIATE createSql;
–添加注释
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.SHE_SHI_CODE IS ‘‘设施编号’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.SHE_SHI_TYPE IS ‘‘设施类型’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.FEN_GONG_SI IS ‘‘分公司’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.SHUI_HAO IS ‘‘水耗’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.PRE_SHUI_HAO IS ‘‘上一小时水耗’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.DIAN_HAO IS ‘‘电耗’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.PRE_DIAN_HAO IS ‘‘上一小时电耗’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.RE_HAO IS ‘‘热耗’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.PRE_RE_HAO IS ‘‘上一小时热耗’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.SHI_JIAN IS ‘‘时间’’’;
EXECUTE IMMEDIATE 'COMMENT ON COLUMN ’ || ‘THTF_TABLE_YEAR_’ || yearStr || ‘.STATE IS ‘‘状态值’’’;
COMMIT;
END IF;
END CREATE_YEAR_TABLE;
如果分区要细化到天,将分区语句改为如下:

PARTITION BY RANGE(SHI_JIAN)
INTERVAL(NUMTOYMINTERVAL(1,’’’ || ‘DAY’ || ‘’’))
( PARTITION PART1 VALUES LESS THAN(TO_DATE(’’’|| CONCAT(yearStr, ‘-01-01’) ||’’’,’’’|| ‘YYYY-MM-DD’ ||’’’)) )’;
创建完分区后,如何查询表中有哪些分区呢?

–查分区数
SELECT table_name,partition_name from user_tab_partitions where table_name = ‘THTF_TABLE_YEAR_2017’
如何查询分区中的数据呢?

–查分区数据
SELECT * FROM THTF_TABLE_YEAR_2017 PARTITION(PART1)

oracle 亿级数据存储方案相关推荐

  1. Oracle亿级数据查询处理(数据库分表、分区实战)

    大数据量的查询,不仅查询速度非常慢,而且还会导致数据库经常宕机(刚接到这个项目时候,数据库经常宕机o(╯□╰)o). 那么,如何处理上亿级的数据量呢?如何从数据库经常宕机到上亿数据秒查?仅以此篇文章作 ...

  2. 分布式数据库中间件Mycat百亿级数据存储(转)

    此文转自: https://www.jianshu.com/p/9f1347ef75dd 2013年阿里的Cobar在社区使用过程中发现存在一些比较严重的问题,如高并发下的假死,心跳连接的故障,只实现 ...

  3. mysql最高qbs_MySQL如何实现万亿级数据存储?

    前言 业界对系统的高可用有着基本的要求,简单的说,这些要求可以总结为如下所示.系统架构中不存在单点问题. 可以最大限度的保障服务的可用性. 一般情况下系统的高可用可以用几个9来评估.所谓的几个9就是系 ...

  4. oracle 亿级数据分页,oracle分页查询千万级优化-Oracle

    oracle分页查询千万级优化,在做比对项目时,有表是3千万多的数据,在页面做分页查询时很卡40s,反正差不多一分钟的时间,后来更了sql,优化了代码就好了很多,4s就可以了. 代码里优化是把总条数存 ...

  5. tidb 企业_TiDB,日均千万级数据存储方案选型

    SQL -> NoSQL -> NewSql

  6. mysql存储value_MySQL key/value存储方案(转)

    需求 250M entities, entities表共有2.5亿条记录,当然是分库的. 典型解决方案:RDBMS 问题:由于业务需要不定期更改表结构,但是在2.5亿记录的表上增删字段.修改索引需要锁 ...

  7. 不用Oracle?基于MySQL数据库下亿级数据的分库分表

    墨墨导读:本文以一个实际的项目应用为例,层层向大家剖析如何进行数据库的优化.项目背景是企业级的统一消息处理平台,客户数据在5千万加,每分钟处理消息流水1千万,每天消息流水1亿左右. 数据库在金融行业怎 ...

  8. 亿级流量系统架构之如何支撑百亿级数据的存储与计算【转载 石杉的架构笔记】-1...

    亿级流量系统架构之如何支撑百亿级数据的存储与计算[石杉的架构笔记] 原创: 中华石杉 "本文聊一下笔者几年前所带的团队负责的多个项目中的其中一个,用这个项目来聊聊一个亿级流量系统架构演进的过 ...

  9. mysql select count 5万条数据很慢_mysql亿级数据数据库优化方案测试银行交易流水记录的查询...

    点击上方△蓝字关注我们 带你征服编程和泡妞两座大山 对MySQL的性能和亿级数据的处理方法思考,以及分库分表到底该如何做,在什么场景比较合适? 比如银行交易流水记录的查询 限盐少许,上实际实验过程,以 ...

最新文章

  1. 专家认为自动驾驶汽车需要很多年的五个原因
  2. Python集合之set()使用方法详解
  3. UWP开发入门(十九)——10分钟学会在VS2015中使用Git
  4. Qt学习之路(17): Qt标准对话框之QMessageBox
  5. let 和 var 的区别
  6. 云计算之KVM虚拟化实战
  7. 在单缓冲区和双缓冲区结构下,读入并分析完该文件的时间分别是
  8. EF框架学习(5)---EF中的在线和离线场景
  9. 华为路由器内部服务器地址映射不起作用,第一次买华为AR2204-s路由,内部服务器映射问题...
  10. java kafka 开发,Kafka JAVA API开发-基础案例
  11. SQL Server 之 修改时不允许保存更改
  12. 使用cboard(oracle数据库)
  13. 2021计算机考研复试攻略(2020复试经验总结)
  14. java jsch执行脚本_JSch远程执行脚本
  15. BAT三巨头谁最先进五百强?
  16. 如何运用3DGIS技术整合智慧社区综合管理解决方案
  17. 零信任时代,开放式安全沙箱让管控更灵活
  18. __wakeup()绕过
  19. 计算机毕业设计ssm龙腾集团员工信息管理系统39r5l系统+程序+源码+lw+远程部署
  20. 最后一天购书优惠!好书必买,不容错过!

热门文章

  1. VS2017中MFC的C++设计中给其它窗口发中文消息
  2. java 去掉空行_java 去掉空行
  3. 幼儿园语言活动包括哪几类_幼儿园语言活动形式有哪些
  4. 什么是软路由和硬路由,两者的区别有什么?
  5. Shell 使用 expr 进行数学运算
  6. 浙江大学计算机考研最新,2017年浙江大学计算机考研复试分数线_浙江大学考研分数线...
  7. SpringBoot+WebSocket问题:Failed to register @ServerEndpoint class
  8. 鸢尾花的分类(四种方法)
  9. IP地址管理常见功能解析
  10. 计算机的操作系统属于什么系统,操作系统是计算机系统中的什么?