mysql--语句优化

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,再进行外层查询。

mysql--语句优化_第1张图片

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

mysql--语句优化_第2张图片

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优化:

mysql--语句优化_第3张图片
mysql--语句优化_第4张图片

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

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

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

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

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

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

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

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

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

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

mysql--语句优化_第5张图片

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

mysql--语句优化_第6张图片

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

13.尽量使用union all替换union

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

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

15.大数据量的limit操作

        使用延迟关联技巧:select id,title from collect where id>=(select id from collect order by id limit 90000,1) limit 10; 

        对于复杂的场景,我们可以建立符合索引(有where 条件,又想走索引用limit的,必须设计一个索引,将where 放第一位,limit用到的主键放第2位,而且只能select 主键) 

        原文地址: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 语句从一个表中选取数据,然后把数据插入另一个表中,常用于创建表的备份复件或者用于对记录进行存档。

你可能感兴趣的:(mysql--语句优化)