zoukankan      html  css  js  c++  java
  • SQL优化

    原文:链接:https://www.jianshu.com/p/06948343681b

    1.框架自带的模型查询比原生的sql要慢

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

            对于上面两条sql来说

            id != 6055  的sql执行时间为0.548秒

            id>6055 or id<6055 的sql执行时间为0.0016秒

    3.in 和 not in 也要慎用,否则会导致全表扫描

            如下图所示:lx_com表是一个千万级数据量的表,ids表是一个只有三个值的表。我们执行如下sql发现耗时19.78秒。

            这是因为:

                select id,name from lx_com where id in (select id from ids)

             并不等价于

                select id,name from lx_com where id in (3,5,7)

            当我们执行 select id,name from lx_com where id in (select id from ids)时候,mysql会变量lx_com 表中上千万的数据,并一一判断是否在select id from ids的范围内,而不是我们平常所想象的先执行select id from ids,再进行外层查询。

            这时候,我们再试一下关联查询,就会发现时间仅用0.01s

    4.对于连续的数值,能用 between 就不要用 in :

            $sql1 ="select id from `dye_production_schedules` where product_id in (2401,2402.2403)";

            $sql2 ="select id from `dye_production_schedules` where product_id between 2400 and 2404";

    5.count优化:

    6.%abc%的查询将导致全表扫描

    7.sql子句中尽量不要进行函数操作,表达式操作

    8.尽可能的使用 varchar 代替 char 

            因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

    9.尽量不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库

            对于varchar 字段来说 null 是不占用任何空间的,查询起来反而还要快

            但是对于char(100)来说,哪怕是null也会占用100字节空间

    10.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的字段。

    11.尽量避免向客户端返回大数据量,若数据量过大,可分批处理

            例1:批量处理数据(可分批向缓存中存贮)避免数组盛放过多的数据 给服务器造成巨大的压力

            例2:大批量数据关联查找我们可以查出主键值,将主键值的数组分成小块,每次只处理小块内的数据

    12.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描

    13.尽量使用union all替换union

            因为union all不过滤,效率高(union去重代价非常高,尽可能的放在程序中去重)

    14.能够用DISTINCT的就不用GROUP BY

    15.大数据量的limit操作

            原文地址:Mysql limit 优化,百万至千万级快速分页 复合索引

    16.向数据库中插入多条数据,拼接成一条sql语句最快

    17.ORDER BY语句的MySQL优化

            ①ORDER BY + LIMIT组合的索引优化

                SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort] LIMIT [offset],[LIMIT];

                这个SQL语句优化比较简单,在[sort]这个栏位上建立索引即可。

           ②WHERE + ORDER BY + LIMIT组合的索引优化

                SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [VALUE] ORDER BY [sort] LIMIT [offset],[LIMIT];

                这个语句,如果你仍然采用第一个例子中建立索引的方法,虽然可以用到索引,但是效率不高。更高效的方法是建立一个联合索引(columnX,sort)

            ③WHERE + IN + ORDER BY + LIMIT组合的索引优化

                SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] IN ([value1],[value2],…) ORDER BY [sort] LIMIT [offset],[LIMIT];

                这个语句如果你采用第二个例子中建立索引的方法,会得不到预期的效果(仅在[sort]上是using index,WHERE那里是using where;using filesort),理由是这里对应columnX的值对应多个。

            ④WHERE+ORDER BY多个栏位+LIMIT

                SELECT * FROM [table] WHERE uid=1 ORDER x,y LIMIT 0,10;

                对于这个语句,大家可能是加一个这样的索引:(x,y,uid)。但实际上更好的效果是(uid,x,y)。这是由MySQL处理排序的机制造成的。

    18.合理使用EXISTS,NOT EXISTS子句

            1.SELECT SUM(T1.C1) FROM T1 WHERE (SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0) 

            2.SELECT SUM(T1.C1) FROM T1 WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2)

            上面两条sql产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。如果你想校验表里是否存在某条纪录,不要用count(*) > 0 那样效率很低,而且浪费服务器资源。可以用EXISTS代替。

    19. 尽量不要用SELECT INTO语句。SELECT INTO 语句会导致表锁定,阻止其他用户访问该表。

            SELECT INTO 语句从一个表中选取数据,然后把数据插入另一个表中,常用于创建表的备份复件或者用于对记录进行存档。

  • 相关阅读:
    小程序组件事件
    关于微信小程序中组件和页面对全局样式的继承性
    创建Java程序并设置快捷提示
    微信小程序设置全局字体
    微信小程序组件的使用
    微信开发者工具的一些快捷键
    消除flex-wrap之后每个item上下的距离
    flex布局中的主轴和侧轴的确定
    C++string中用于查找的find系列函数浅析
    C++11 图说VS2013下的引用叠加规则和模板参数类型推导规则
  • 原文地址:https://www.cnblogs.com/kitor/p/12744560.html
Copyright © 2011-2022 走看看