公司在千万级别数据上线项目上出现的问题 以及 相应需要注意的点(转)

上几个月一直很忙, 也没时间回顾和整理做的 一些东西 和 知识。

    这里记载以下, 当时公司给石家庄做了一个比较大的项目, 里面 好几张表的数据 是千万级别的,  还有 好多张也是百万级别的, 自然, 表的数量之多也是不用多说了, 不过在问题出现后, 也就牵扯出了很多,在这个问题方面,公司也是 技术经理开会 我们对于这个问题进行了相应的学习 和 重视。

    其实很重要的,有经验 和没有经验,公司整体项目一开始的规划, 整体的设计,架构层面可能没有那么全面,至于项目中的问题,在 上线2年多后爆发,这个就可以看的出来代码的质量真的也是尤其重要的,所以较大的公司 会对提交的代码进行审核,会进行评审, 会有规范。

     这次的问题, 就出在了可以说是  数据库 和 SQL 的优化方面。 表结构相应的问题(当然可能是老项目,一开始没有那么注重), 代码中 sql 语句的问题,导致了最主要有系统中有2个页面直接瘫痪, 一方面可能是 访问用户并发压力的问题, 一方面就是 查询数据方面sql的问题(sql 执行30秒以上  timeout)。

     因为内部资料就不上传展示了, 实质的问题还是要注意的,我总结了下:

    1.  避免全表扫描

    2. 对大 数据表  尽量避免频繁链接操作  和 查询

    3.  乱用已经建好的视图( 视图中有需要的数据但是关联很多)  -   其中有说到一句,就是我看到这个视图里面有我需要的数据我就直接用这个,从里面取。

    4. 查询不必要的数据(类似select  *) 避免返回不必要的行和列 (这个很重要 相当重要)

          举个(真实)例子 ,  有1张表。

         1000万条数据全表(里面字段很多)查询    耗时  20秒                    只查询   ID  Name   address  只耗时了   12秒

         1000万条数据 查询 ID  和 address  耗时   10  秒                              1000万条数据 查询 ID  和 name    耗时   6 秒 

         当然其中问题就自己看吧, address 和 name 的内容量大小肯定是不一样的辣。

    5.  建表时 字段设置大小的问题  例如   name  varchar(128)     这个问题还是相当严重的根本不可能会用到

          为什么这样类,因为数据库的存储 实质也是按照文件的存储方式存储数据的。 这个当时说是,按照8M 每一页存储的, 你想想,如果刚好要查

          数据  跑到 1  2  3页查询 这个应该是会有问题的。一定要

    6.  缓存的设计

    7. 应尽量避免在 where 子句中使用!=或<>操作符,否则引擎放弃使用索引而进行全表扫描。

    8.  对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

    9.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
          select id from t where num is null
          可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
          select id from t where num=0

    10.应尽量避免在 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=20

    11.下面的查询也将导致全表扫描:(不能前置百分号)
          select id from t where name like ‘%abc%’
         若要提高效率,可以考虑全文检索。

    12.in 和 not in 也要慎用,否则会导致全表扫描,如:
         select id from t where num in(1,2,3)
         对于连续的数值,能用 between 就不要用 in 了:
        select id from t where num between 1 and 3 

    13.   如果查询的两个表大小相当,那么用in和exists差别不大。     

         in:  
        例如:表A(小表),表B(大表)

         1:select * from A where cc in (select cc from B) 效率低,用到了A表上cc列的索引;     

         select * from A where exists(select cc from B where cc=A.cc)   效率高,用到了B表上cc列的索引。   

        相反的

         2:select * from B where cc in (select cc from A)  效率高,用到了B表上cc列的索引;

          select * from B where exists(select cc from A where cc=B.cc)  效率低,用到了A表上cc列的索引。 

     14.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些

     15.  这个也是非常重要 要说的1点。

             数据库3范式, 这个估计软件工程专业的在学校就学过了。 反正我是有学过辣= =。

            其中有1点  字段不冗余, 

            但是,在特殊的情况下是 可以 冗余的 特殊情况(需要频繁的链接 查询  操作大数据表, 或者核心数据业务大数据量的表 ,在冗余字段的情况下 可避免也是允许的)

      16.   数据库表的分区表

               物理分区表

               (类似于   主要将2014年数据存在一起    2015年数据存在一起   业务不牵扯)

       17. SQL Server Profiler 的使用

           

     

     18.  索引        当然并不一定创建索引   不一定就会快。 一定要真的去理解和研究过(一定要对 这个很了解,后面我也会详细看下)

     19.  存储过程

      

      

      从中学习到了很多, 也希望大家 能够学习到,就拿出来分享了,当然这只是部分, 还有很多东西 需要学习  和 推敲 。  

      转载请注明出处,谢谢。
--------------------- 
作者:空白的泡 
来源:CSDN 
原文:https://blog.csdn.net/kongbaidepao/article/details/46603887 
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值