SQL性能简单优化(作为初级程序员的想法)

Wesley13
• 阅读 306

随笔背景:虽然参与正式项目开发已经近两年了,但是之前涉及的数据都不是很大,就算数据量够了,但是也没涉及到统计,所以之前开发的时候仅仅注意业务逻辑是否正确,代码是否精简。本次做的一个项目,写数据统计的接口,刚开始也只是注意逻辑,不过后来数据量仅仅到了40万的时候,一个按照年龄区段获取各年龄的普及率接口竟然花了近一分钟,所以开始了我的优化路程。

一、从SQL上来看,首先想到的是把SQL上的业务逻辑拿出来,放到代码里面实现。比如这里根据年龄区段获取各年龄的普及率,可以把拆成两个SQL,一个统计各年龄段总人数,一个统计各年龄段普及的人数,具体计算比例可以在代码实现。原理是SQL里面加上逻辑处理的话是针对大数量的逻辑处理,而代码处理的话仅仅是对已经统计过的数据处理,这样对比一下逻辑处理的对象就知道为啥快点了。

如: select sum(case when a.answer != '01' then 1 else 0 end)/count(a.id) pjl from tableA a group by a.age  

拆分: select count(a.id) from tableA a  where a. answer != '01' group by a.age

    select count(a.id) from tableA a where group by a.age

二、不是说所有的子查询都会比较慢,都是不好的。个人之前觉得子查询很耗性能,明明可以关联查询的,为什么还要子查询。然后本次发现其实合理的利用子查询可以有效的提高速率,如可以通过子查询筛选一部分数据,然后再对筛选后的数据关联。

如:select a.name,a.code from tableA a left join tableB b on b.code = a.code  where b.status = '2'  

修改:select a.name,a.code from tableA a where a.code in (select code from tableB where status = '2')

原SQL是先关联然后筛选数据的,关联笛卡尔积 乘法的概念,可以理解为先把所有数据进行比对,比如一个tableA 4条,一个tableB 5条,那就是比对4*5 = 20次

而先筛选一次的话,就是意味着先对tableB筛选,筛选出3条,然后在对tableA筛选,5+4 = 9次 数据量小还无所谓,那数量大的话。。。。

三、where条件后面的筛选条件位置有影响

mysql where 执行顺序从左到右 也就意味着把过滤效果最大的放在最上面或者说靠where越近

oracle where 执行顺序从右到左 也就意味着把过滤效果最大的放在最下面或者说靠where越远

表的位置也符合这规律(表位置没试过,网上说的)

四、查询列时,尽量不用* 用具体的参数,以前写代码图方便经常写个* ,其实有的时候根本用不到那么多属性,所以查的少当然快点咯

如: select * from tableA

改成:select name,code from tableA

五、如果表加了索引的字段,书写值一定要规范,如例子虽然也能查出正确的结果,不过此时该字段查询索引未生效,所以还是稍微麻烦点打上‘’

如:select code from tableB where status = 2     (表字段status为char类型)

修改:select code from tableB where status = '2'

六、从表的方面可以把需要筛选的字段加上索引,效果就像开了挂一样哈哈,反正我的语句我觉得就是索引加的从一分钟到了20秒,个人觉得这个很好用

以上就是本次优化性能用到的方法,不过影响性能的不仅仅是这些方面,比如还有数据库本身的影响,我们的数据库是开发用的16G mysql,总而言之每个地儿都扣点,性能当然快很多了,积水成渊嘛。额,以上的想法只是本人本次试过的方法,有些原理可能还是漏洞百出(不过我确实快了。。),虽然40万数据其实也没多少,相比那些百万千万,甚至亿级的,抱歉我还很菜,这种的找我老大,我还是咸鱼一条。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
2年前
sql注入
反引号是个比较特别的字符,下面记录下怎么利用0x00SQL注入反引号可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景,下面具体说下1)表名payload:select\from\users\whereuser\_id1limit0,1;!(https://o
Stella981 Stella981
2年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这