惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
GbyAI
GbyAI
G
Google Developers Blog
大猫的无限游戏
大猫的无限游戏
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 叶小钗
A
About on SuperTechFans
M
MIT News - Artificial intelligence
宝玉的分享
宝玉的分享
雷峰网
雷峰网
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Martin Fowler
Martin Fowler
Google DeepMind News
Google DeepMind News
博客园 - Franky
B
Blog RSS Feed
Y
Y Combinator Blog
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
Last Week in AI
Last Week in AI
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
罗磊的独立博客
Apple Machine Learning Research
Apple Machine Learning Research

博客园 - AK47+

(转)racle 9i 数据库设计指引全集(4) (转)Oracle 9i 数据库设计指引全集(3) (转)Oracle 9i 数据库设计指引全集(2) (转)Oracle 9i 数据库设计指引全集(1) (转)关于Oracle数据库中索引的维护经验谈 (转)oracle 分区表的建立方法 (转)关于oracle表空间的规划方法 (转)Oracle 分区索引详解 oracle startup时 ORA-00600错误解决 转:何时使用绑定变量性能反而差 (转)ORACLE 中ROWNUM用法总结! 跪求思路:大批量数据导出 阳春三月,放飞希望---希望今年不再碌碌无为 仓颉如果来做软件,一定是一位开山式人物 关于面试的一点感受 复习功课:对进程、线程、应用程序域的理解 园子里的兄弟,谁到这家公司面试过,来评一下笔试题了 推荐:一道让我惦记了一年的机试题 两个异常:a circular reference was detected while serializing及 Maximum length exceeded
项目总结
AK47+ · 2009-02-27 · via 博客园 - AK47+

      通过去年做的一个项目我体会到,数据量大了以后,看似简单的问题都变得让人寝食难安,在解决问题的过程中收集了不少好文章,集中在此,方便自己查阅。

oracle 9i 数据库设计指引全集(1)         oracle 9i 数据库设计指引全集(2)    oracle 9i 数据库设计指引全集(3)

oracle 9i 数据库设计指引全集(4)         oracle 分区表的建立方法             关于oracle表空间的规划方法

关于Oracle数据库中索引的维护经验谈    Oracle 分区索引详解             何时使用绑定变量性能反而差

ORACLE 中ROWNUM用法总结

      先说一下项目的情况,做的是一个治安卡口软件,在进出城市的主要路口安装摄像机,记录过往车辆的相关信息(车牌号码、通过时间、车速等等),把采集到的车辆信息传至中心服务器存储,供相关业务部门进行布控、查询、违法处罚等,业务很简单,就是数据量巨大(想想一个路口一天要过多少车,10个路口,20个......)业主要求保留近3个月的记录.

系统在运行了过程中,随着数据量的增加,问题不断的出现,2000万、4000万......每次都是一次折磨

一个功能是按照一些条件对过往车辆进行查询,由于过往车辆表的数据库太大,查询的响应时间成了大问题
下面是遇到的一些问题:

1. 限制一次可以查询的最多记录数

我的办法是根据计算记录总数,得到记录总数后生成分页导航,再载入当前页数据。
利用rownum进行分页,分页的办法:
select *
from (selet rownum as  rn,t.* from t where ...)
where rn > pageleft and rn <=pageright  

在开发阶段由于测试环境的数据量很小,没出现什么问题,到了实际环境问题来了,用户查询一段时间通过的车辆,计算个记录总数就需要很长时间,我自己都不能忍受,更不用说用户了。

找点理由:即使我把这几十万、上百万的记录返回给了,有什么用呢?用户需要的是尽量精确的记录,返回的记录数越少越有价值,用户不会在几十万条记录中一条一条的去找。所以可以限制一次能够查询的记录总数,比如只返回前1万条;

郁闷的同时我也在想:google是怎么做分页?

从google的搜索结果中我注意到两点:
1.顶部给出的查询结果总数不是精确值,而是“约有…” ,不是即时计算的。

2.如果查询1000条后的记录,修改url中的start后的参数:
http://www.google.cn/search?hl=zh-CN&newwindow=1&q=dudu&start=1001&sa=N
会出现“对不起,Google 为所有查询的结果数都不会超过 1000 个。 (您所请求的结果在第 1001 个之后。)”

了解到了这些,我理直气壮的跟用户说:我要限制一次能够返回的记录的数量。

于是修改为:
select *
from (selet rownum as  rn,t.* from t where ... and rownum < maxRow )
where rn > pageleft and rn <=pageright

修改后的查询比以前快了一些,我想了想,其实不用rownum<maxRow 只要 
select *
from (selet rownum as  rn,t.* from t where ... and rownum <= pagerright)
where rn >= pageleft and rn < pageright  即可,

修改后再试,又快了一些;发现翻页时,随着页码的增加,响应时间也逐渐增大,这是肯定的了,rownum<=10和rownum<=1000肯定不一样的了。

2. 不计算count

      过了一两个月,用户又打电话来了,说有些组合条件查询很慢,甚至没有响应。到现场看看,查一下现在有多少数据,执行了个select count(*) ,竟然等了十几分钟才出来结果,记录数是3500多万条,后来调试程序,发现真正取得一页数据还是比较快的,耗费时间的操作是计算记录总数,把sql语句直接放到pl sql 中执行也需要几分钟才能出来结果,靠,这个select count 要这么长时间,算了,不计算查询结果的总数了。不计算记录总数,还要分页,想了一些办法解决了。修改后查询速度快了很多,这两个月通过对oracle的学习,俺已经认识到这么大的数据量应该对主表进行分区了。

3. 按照时间对主表进行分区

     按照时间对过往车辆表进行分区无疑是最合适的。
    如果一个月建一个分区,我可以预先建出来未来半年或一年的分区,例如2008-07-01 00:00:00 到2008-08-01 00:00:00 之间的记录在一个分区,2008-08-01 00:00:00 到2008-09-01 00:00:00 之间的记录又是一个分区;这样做的问题是过半年我需要到现场再创建以后的分区,删除以前作废的分区,不是个好办法。
    最后想到的办法是按照月份建12个分区,按照记录的时间字段所在的月份映射到对应的月份分区。不管是08年7月的还是09年7月的记录,均映射到7月的分区。
    按照月份分区后,效果很明显。 

4. 定期对表进行统计分析  

5. 一个教训是:使用绑定变量方式和直接赋值方式的执行计划可能是不一样的;当发现某个查询的速度比预期的慢的很多,很可能是sql语句执行时使用了错误的查询计划,这个时候就需要去查找原因了。

6.数据量大,增长快,数据的备份也不容易了。