zoukankan      html  css  js  c++  java
  • 项目总结2

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

    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.数据量大,增长快,数据的备份也不容易了。

  • 相关阅读:
    Python/WSGI 应用快速入门--转
    汇编题目:数字转字符,并在窗口上显示出来
    汇编题目:在窗口上显示Welcome to masm!
    VBA中的函数Timer用法
    用VBA计算两个日期之间的工作日(去掉周末两天)
    VBA记录当前系统时间并精确到毫秒
    上海房产税免征--积分或居住证
    学习汇编语言
    “Hello World”—— 第一个汇编程序
    汇编程序设计上机步骤
  • 原文地址:https://www.cnblogs.com/baiduligang/p/4247340.html
Copyright © 2011-2022 走看看