浅谈sql优化

前言:关于sql优化一直是一个比较重要的问题,在此,从四个方面进行的分析

1、数据库方面

 (1)、分库:
             分库,简而言之就是把数据按照不同的规格,模式来分开成不同的库。
             可以按照业务来分,例如:商品表分在商品库,订单表分在订单库里,用户表分在用户库里。
             如果按照业务来分的话,就需要处理跨库了。
             也可以通过取模的方式路由,一种常见的路由策略:
             1、中间变量 = user_id%(库数量*每个库的表数量);
             2、库序号 = 取整(中间变量/每个库的表数量);
             3、表序号 = 中间变量%每个库的表数量;
             例如:数据库有256 个,每一个库中有1024个数据表,用户的user_id=262145,按照上述的路由策略,
             可得:
             1、中间变量 = 262145%(256*1024)= 1;
             2、库序号 = 取整(1/1024)= 0;
             3、表序号 = 1%1024 = 1;
(2)、分区
             分区,就是将一个数据量比较大的表,用某种方法把数据从物理上分成若干个小表来存储(类似水平表),
             从逻辑来看还是一个大表。分表最大分1024,一般分100左右比较合适。
             使用场景是:
                    对于这种数据库比较多,但是并发不是很多的情况下,可以采用表分区。
                    对于数据量比较大的,但是并发也比较高的情况下,可以采用分表和分区相结合。
(3)、分表
             分表,分为水平分表和垂直分表。
             水平分表:
                    原理:用户ID取模,如果不是整数,可以首先将其进行hash获取到整数。
                    所遇问题:
                          1. 跨表直接连接查询无法进行
                          2. 我们需要统计数据的时候
                          3. 如果数据持续增长,达到现有分表的瓶颈,需要增加分表,此时会出现数据重新排列的情况 
                    解决方案:
                          1.第1,2点可以通过增加汇总的冗余表,虽然数据量很大,但是可以用于后台统计或者查询时效性比较底的情况,而且我们可以提前算好某个时间点或者时间段的数据。
                          2.第三点解决建议:可以开始的时候,就分析大概的数据增长率,来大概确定未来某段时间内的数据总量,从而提前计算出未来某段时间内需要用到的分表的个数。
                          考虑表分区,在逻辑上面还是一个表名,实际物理存储在不同的物理地址上。
                          考虑分库。
             垂直分表:
                    原则:1. 把大字段独立存储到一张表中
                               2. 把不常用的字段单独拿出来存储到一张表
                               3. 把经常在一起使用的字段可以拿出来单独存储到一张表
                    标准:
                               1.表的体积大于2G并且行数大于1千万
                               2.表中包含有text,blob,varchar(1000)以上
                               3.数据有时效性的,可以单独拿出来归档处理

2、sql语句方面

    (1)、多表连接优化:
    
              采用少对多,不要采用多对少。举个例子:如果有一张10条数据的表,对应一张1000条数据的表,
              哪怕全表检索,也只需要走10次,而如果用1000条对应10条数据,全表走的话,需要1000次,直
              接翻了100倍。效率可想而知。
              
              笛卡尔积(交叉连接):在MySql中可以为CROSS JOIN或省略CROSS即JOIN,或者使用","。
              由于其返回的结果为被连接的两个数据表的乘积,因此当没有WHERE, ON或USING条件的时候
              一般不建议使用,因为当数据表项目太多的时候,会非常慢。一般使用LEFT [OUTER] JOIN
              或者RIGHT [OUTER] JOIN。
    (2)、关键字:
    
              in:in关键字会进行全表检索,比如有id为5、6、7的条件,那么采用in关键字的话,查询到5之后
              还会接着往下走,查询到6也会接着往下走。这样就会造成很多不必要的检索。可以将其替换为
              exists关键字,这个关键字的话,走到5的时候会停下,之后走到6也会停下,不会造成不必要的
              检索。而对于区间来说,between and显然更合适,直接锁定区间,更为高效。

你可能感兴趣的:(数据库)