保健励志美文体育育儿作文
投稿投诉
作文动态
热点娱乐
育儿情感
教程科技
体育养生
教案探索
美文旅游
财经日志
励志范文
论文时尚
保健游戏
护肤业界

8种最坑的SQL错误用法,你有没有踩过?

  来源:yq。aliyun。comarticles72501
  1、LIMIT语句
  2、隐式转换
  3、关联更新、删除
  4、混合排序
  5、EXISTS语句
  6、条件下推
  7、提前缩小范围
  8、中间结果集下推
  总结
  sql语句的执行顺序:FROM
  lefttable
  ON
  joincondition
  jointype
  JOIN
  righttable
  WHERE
  wherecondition
  GROUPBY
  groupbylist
  HAVING
  havingcondition
  SELECT
  DISTINCT
  selectlist
  ORDERBY
  orderbycondition
  LIMIT
  limitnumber
  1、LIMIT语句
  分页查询是最常用的场景之一,但也通常也是最容易出问题的地方。比如对于下面简单的语句,一般DBA想到的办法是在type,name,createtime字段上加组合索引。这样条件排序都能有效的利用到索引,性能迅速提升。SELECT
  FROMoperation
  WHEREtypeSQLStats
  ANDnameSlowLog
  ORDERBYcreatetime
  LIMIT1000,10;
  好吧,可能90以上的DBA解决该问题就到此为止。但当LIMIT子句变成LIMIT1000000,10时,程序员仍然会抱怨:我只取10条记录为什么还是慢?
  要知道数据库也并不知道第1000000条记录从什么地方开始,即使有索引也需要从头计算一次。出现这种性能问题,多数情形下是程序员偷懒了。
  在前端数据浏览翻页,或者大数据分批导出等场景下,是可以将上一页的最大值当成参数作为查询条件的。SQL重新设计如下:SELECT
  FROMoperation
  WHEREtypeSQLStats
  ANDnameSlowLog
  ANDcreatetime2017031614:00:00
  ORDERBYcreatetimelimit10;
  在新设计下查询时间基本固定,不会随着数据量的增长而发生变化。
  2、隐式转换
  SQL语句中查询变量和字段定义类型不匹配是另一个常见的错误。比如下面的语句:mysqlexplainextendedSELECT
  FROMmybalanceb
  WHEREb。bpn14000000123
  ANDb。isverifiedIS;
  mysqlshowwarnings;
  Warning1739Cannotuserefaccessonindexbpnduetotypeorcollationconversiononfieldbpn
  其中字段bpn的定义为varchar(20),MySQL的策略是将字符串转换为数字之后再比较。函数作用于表字段,索引失效。
  上述情况可能是应用程序框架自动填入的参数,而不是程序员的原意。现在应用框架很多很繁杂,使用方便的同时也小心它可能给自己挖坑。
  3、关联更新、删除
  虽然MySQL5。6引入了物化特性,但需要特别注意它目前仅仅针对查询语句的优化。对于更新或删除需要手工重写成JOIN。
  比如下面UPDATE语句,MySQL实际执行的是循环嵌套子查询(DEPENDENTSUBQUERY),其执行时间可想而知。UPDATEoperationo
  SETstatusapplying
  WHEREo。idIN(SELECTid
  FROM(SELECTo。id,
  o。status
  FROMoperationo
  WHEREo。group123
  ANDo。statusNOTIN(done)
  ORDERBYo。parent,
  o。id
  LIMIT1)t);
  执行计划:
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1PRIMARYoindexPRIMARY824Usingwhere;Usingtemporary
  2DEPENDENTSUBQUERYImpossibleWHEREnoticedafterreadingconsttables
  3DERIVEDorefidx2,idx5idx58const1Usingwhere;Usingfilesort
  重写为JOIN之后,子查询的选择模式从DEPENDENTSUBQUERY变成DERIVED,执行速度大大加快,从7秒降低到2毫秒。UPDATEoperationo
  JOIN(SELECTo。id,
  o。status
  FROMoperationo
  WHEREo。group123
  ANDo。statusNOTIN(done)
  ORDERBYo。parent,
  o。id
  LIMIT1)t
  ONo。idt。id
  SETstatusapplying
  执行计划简化为:
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1PRIMARYImpossibleWHEREnoticedafterreadingconsttables
  2DERIVEDorefidx2,idx5idx58const1Usingwhere;Usingfilesort
  4、混合排序
  MySQL不能利用索引进行混合排序。但在某些场景,还是有机会使用特殊方法提升性能的。SELECT
  FROMmyordero
  INNERJOINmyappraiseaONa。orderido。id
  ORDERBYa。isreplyASC,
  a。appraisetimeDESC
  LIMIT0,20
  执行计划显示为全表扫描:
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1SIMPLEaALLidxorderid1967647Usingfilesort
  1SIMPLEoeqrefPRIMARYPRIMARY122a。orderid1
  由于isreply只有0和1两种状态,我们按照下面的方法重写后,执行时间从1。58秒降低到2毫秒。SELECT
  FROM((SELECT
  FROMmyordero
  INNERJOINmyappraisea
  ONa。orderido。id
  ANDisreply0
  ORDERBYappraisetimeDESC
  LIMIT0,20)
  UNIONALL
  (SELECT
  FROMmyordero
  INNERJOINmyappraisea
  ONa。orderido。id
  ANDisreply1
  ORDERBYappraisetimeDESC
  LIMIT0,20))t
  ORDERBYisreplyASC,
  appraisetimeDESC
  LIMIT20;
  5、EXISTS语句
  MySQL对待EXISTS子句时,仍然采用嵌套子查询的执行方式。如下面的SQL语句:SELECT
  FROMmyneighborn
  LEFTJOINmyneighborapplysra
  ONn。idsra。neighborid
  ANDsra。useridxxx
  WHEREn。topicstatus4
  ANDEXISTS(SELECT1
  FROMmessageinfom
  WHEREn。idm。neighborid
  ANDm。inuserxxx)
  ANDn。topictype5
  执行计划为:
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1PRIMARYnALL1086041Usingwhere
  1PRIMARYsrarefidxuserid123const1Usingwhere
  2DEPENDENTSUBQUERYmrefidxmessageinfo122const1Usingindexcondition;Usingwhere
  去掉exists更改为join,能够避免嵌套子查询,将执行时间从1。93秒降低为1毫秒。SELECT
  FROMmyneighborn
  INNERJOINmessageinfom
  ONn。idm。neighborid
  ANDm。inuserxxx
  LEFTJOINmyneighborapplysra
  ONn。idsra。neighborid
  ANDsra。useridxxx
  WHEREn。topicstatus4
  ANDn。topictype5
  新的执行计划:
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1SIMPLEmrefidxmessageinfo122const1Usingindexcondition
  1SIMPLEneqrefPRIMARY122ighborid1Usingwhere
  1SIMPLEsrarefidxuserid123const1Usingwhere
  6、条件下推
  外部查询条件不能够下推到复杂的视图或子查询的情况有:
  1、聚合子查询;2、含有LIMIT的子查询;3、UNION或UNIONALL子查询;4、输出字段中的子查询;
  如下面的语句,从执行计划可以看出其条件作用于聚合子查询之后:SELECT
  FROM(SELECTtarget,
  Count()
  FROMoperation
  GROUPBYtarget)t
  WHEREtargetrmxxxx
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1PRIMARYderived2ref514const2Usingwhere
  2DERIVEDoperationindexidx4idx451920Usingindex
  确定从语义上查询条件可以直接下推后,重写如下:SELECTtarget,
  Count()
  FROMoperation
  WHEREtargetrmxxxx
  GROUPBYtarget
  执行计划变为:
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1SIMPLEoperationrefidx4idx4514const1Usingwhere;Usingindex
  关于MySQL外部条件不能下推的详细解释说明请参考以前文章:MySQL性能优化条件下推到物化表http:mysql。taobao。orgmonthly20160708
  7、提前缩小范围
  先上初始SQL语句:SELECT
  FROMmyordero
  LEFTJOINmyuserinfou
  ONo。uidu。uid
  LEFTJOINmyproductinfop
  ONo。pidp。pid
  WHERE(o。display0)
  AND(o。ostaus1)
  ORDERBYo。selltimeDESC
  LIMIT0,15
  该SQL语句原意是:先做一系列的左连接,然后排序取前15条记录。从执行计划也可以看出,最后一步估算排序记录数为90万,时间消耗为12秒。
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1SIMPLEoALL909119Usingwhere;Usingtemporary;Usingfilesort
  1SIMPLEueqrefPRIMARYPRIMARY4o。uid1
  1SIMPLEpALLPRIMARY6Usingwhere;Usingjoinbuffer(BlockNestedLoop)
  由于最后WHERE条件以及排序均针对最左主表,因此可以先对myorder排序提前缩小数据量再做左连接。SQL重写后如下,执行时间缩小为1毫秒左右。SELECT
  FROM(
  SELECT
  FROMmyordero
  WHERE(o。display0)
  AND(o。ostaus1)
  ORDERBYo。selltimeDESC
  LIMIT0,15
  )o
  LEFTJOINmyuserinfou
  ONo。uidu。uid
  LEFTJOINmyproductinfop
  ONo。pidp。pid
  ORDERBYo。selltimeDESC
  limit0,15
  再检查执行计划:子查询物化后(selecttypeDERIVED)参与JOIN。虽然估算行扫描仍然为90万,但是利用了索引以及LIMIT子句后,实际执行时间变得很小。
  idselecttypetabletypepossiblekeyskeykeylenrefrowsExtra
  1PRIMARYderived2ALL15Usingtemporary;Usingfilesort
  1PRIMARYueqrefPRIMARYPRIMARY4o。uid1
  1PRIMARYpALLPRIMARY6Usingwhere;Usingjoinbuffer(BlockNestedLoop)
  2DERIVEDoindexidx15909112Usingwhere
  8、中间结果集下推
  再来看下面这个已经初步优化过的例子(左连接中的主表优先作用查询条件):SELECTa。,
  c。allocated
  FROM(
  SELECTresourceid
  FROMmydistributed
  WHEREisdelete0
  ANDcusmanagercode1234567
  ORDERBYsalecodelimit20)a
  LEFTJOIN
  (
  SELECTresourcesid,sum(if(allocation,0)12345)allocated
  FROMmyresources
  GROUPBYresourcesid)c
  ONa。resourceidc。resourcesid
  那么该语句还存在其它问题吗?不难看出子查询c是全表聚合查询,在表数量特别大的情况下会导致整个语句的性能下降。
  其实对于子查询c,左连接最后结果集只关心能和主表resourceid能匹配的数据。因此我们可以重写语句如下,执行时间从原来的2秒下降到2毫秒。SELECTa。,
  c。allocated
  FROM(
  SELECTresourceid
  FROMmydistributed
  WHEREisdelete0
  ANDcusmanagercode1234567
  ORDERBYsalecodelimit20)a
  LEFTJOIN
  (
  SELECTresourcesid,sum(if(allocation,0)12345)allocated
  FROMmyresourcesr,
  (
  SELECTresourceid
  FROMmydistributed
  WHEREisdelete0
  ANDcusmanagercode1234567
  ORDERBYsalecodelimit20)a
  WHEREr。resourcesida。resourcesid
  GROUPBYresourcesid)c
  ONa。resourceidc。resourcesid
  但是子查询a在我们的SQL语句中出现了多次。这种写法不仅存在额外的开销,还使得整个语句显的繁杂。使用WITH语句再次重写:WITHaAS
  (
  SELECTresourceid
  FROMmydistributed
  WHEREisdelete0
  ANDcusmanagercode1234567
  ORDERBYsalecodelimit20)
  SELECTa。,
  c。allocated
  FROMa
  LEFTJOIN
  (
  SELECTresourcesid,sum(if(allocation,0)12345)allocated
  FROMmyresourcesr,
  a
  WHEREr。resourcesida。resourcesid
  GROUPBYresourcesid)c
  ONa。resourceidc。resourcesid
  总结
  数据库编译器产生执行计划,决定着SQL的实际执行方式。但是编译器只是尽力服务,所有数据库的编译器都不是尽善尽美的。
  上述提到的多数场景,在其它数据库中也存在性能问题。了解数据库编译器的特性,才能避规其短处,写出高性能的SQL语句。
  程序员在设计数据模型以及编写SQL语句时,要把算法的思想或意识带进来。
  编写复杂SQL语句要养成使用WITH语句的习惯。简洁且思路清晰的SQL语句也能减小数据库的负担。

关于大雪的作文大雪每年12月7日或8日,太阳黄经达255度时为二十四节气之一的大雪。大雪,顾名思义,雪量大。古人云:大者,盛也,至此而雪盛也。到了这个时段,雪往往下得大、范围也广,故名大雪。……单元作文给妈妈的一封信品学网专稿未经允许不得转载亲爱的妈妈:您最近怎么样?工作顺利吗?远方的你,知道长春正在下大雪吗?雪,纷纷扬扬地下个不停,时而像一个个穿着银色凯甲的勇士,时而像……我学会了溜冰作文300字我学会了溜冰有一次,我看见别人在广场那里溜冰,觉得很酷,我也想学,就让妈妈给我买了一双溜冰鞋。第二天,我和妈妈来到广场上学溜冰。首先,我穿好溜冰鞋站起来。妈妈扶着我,但是……外围暴跌!A股今日还能稳住吗?外围市场美股三大指数大幅收跌,纳指跌4。99,标普500指数跌3。56,道指跌3。12。互联网零售概念股、大型科技股、热门中概股集体重挫。苹果收跌5。57,脸书跌6……伤心的句子导语:总有那么几个时候是伤心的,这样您才能逐渐成熟,是大哭一场?是空洞的发呆?还是捧起一本书沉浸于另一个世界?下面是小编收集的一些伤感句子,供欣赏,希望能得到您的共鸣。1……种植园日记400字今天下午,我们班去种植园看我们种的玉米、辣椒、梅豆等植物的生长情况。到了种植园,我们从远处看,别的班的种的辣椒很绿而且很高,而我们的就差的很多,我想:都是在同一个地方同一……运动是我的挚友七年级作文我们的生活总在繁忙的学习与工作中度过,从来不曾考虑其他的,可是你有没有想过,如果没有健康的身体作为前提条件,再好的学习成绩,也是无用的。在这次体育文化节中我就感受到了,以后我也……划船三年级作文告别快乐已经很久很久了,那些在我身上发生的事都已经被时间之水冲刷得看不出色彩,唯独那一次划船如同山间淙淙的小溪,一直印在我心里。那是我上小学的第二个暑假,我和李家涛在河边……写母爱的经典作文母爱是一碗姜汤,让你久久回味;母爱是一个方向,让你迷途知返;母爱是一缕清风,让你在酷热的夏季感到丝丝阴凉。有一次考试,我满以为自己能考个高分,却没有想到,试卷上的88清晰……大拇指汤姆开店小学作文童话王国里,每一只动物都开了一家小店,就只有大拇指汤姆、锡兵和纸做的姑娘没有开店。他们三个看见别人都了点,只有自己没有开店,他们也心动了。于是,汤姆就把锡兵和纸姑娘都叫了……关于难忘的中秋节作文(通用7篇)在学习、工作、生活中,大家都写过作文吧,作文可分为小学作文、中学作文、大学作文(论文)。如何写一篇有思想、有文采的作文呢?下面是小编精心整理的关于难忘的中秋节作文(通用7篇),……我爱冬天作文800字一阵阵风刮过来,一片片黄叶渐渐落下,归人黄土,一个个行人从街头路过,他们匆匆向家中走去。而我,望着冷清的大街,捡起一片火红的枫叶,夹进书中,闻那一抹书的清香,我静静地坐在一条长……
外媒称赞北京冬奥会上的高新技术来源:人民日报海外版中国在本届冬奥会上使用了多项数字技术。为了尽可能减少人员接触,主办方在会场各处设置机器人,还积极使用5G技术。本届冬奥会上,主办方除了在赛场和相关设施……荷兰发现毒力和传染性更强艾滋病病毒(HIV)变体毒株科技日报北京2月7日电(实习记者张佳欣)据英国牛津大学研究人员领导的一项研究,荷兰发现了一种新的艾滋病病毒(HIV)毒株,毒力更强、更具传染性。它被命名为HIV1亚型病毒(VB……自己鼓励自己作文一天,我看了一本好的书,从那起,我便开始鼓励自己、为自己加油,遇到困难从来都不会放弃,只会坚持。它这一本书很有魔力,会让我想起了一件事。记得在二年级时,我们开始考试了,大……书狂谢何斌同学作文我的同学中,只有谢何斌是和我一样最爱读书的,所以,我给他取了一个外号,叫书狂,也就是说谢何斌读书读到发狂啦。这谢何斌经常为一本书而不择手段。最近,班上刮起了一阵哈里波特风……初二读后感作文来自星星的你还记得半年多前给我们带来太多感动的《来自星星的你》,在这其中,我得到了不少启示。电视剧中的千颂伊是个有名的明星,因此电视剧的主角宝座非她莫属,她有两个好朋友,洪福子是一个……小学生写运动会的作文十月,秋风和熙,阳光明媚。我们也开始了校园运动会。下面语文迷为大家提供了写运动会的作文范文,希望对你有帮助。写运动会的作文一一年一度的运动会终于来了。星期四的早上,……被撕毁的作业E度网专稿未经允许不得转载ldquo;唰mdash;mdash;唰唰mdash;mdash;rdquo;我噙着眼泪,瑟瑟地站在墙角,地上横七竖八地躺着几张作业碎片,好像在……三年级春天作文350字导语:春,是一年四季中最美的,也是最会装扮自己的。下面是小编整理的关于春天的作文,欢迎大家认真阅读!【作文1:我发现春来了】春,是一年四季中最美的,也是最会装扮自己……忽然看见一幅熟悉的画,这不是梦里的小女孩吗?我吃惊的望着,又急忙收回看画的目光。我顿时害怕起来,我不敢看它们的脸,因为它们没有眼睛!我越想越害怕,那个小女孩为什么会……美丽的白玉兰写景作文在我们学校的阶梯教室旁,有几棵美丽的白玉兰。他们有着一种屈尊降贵的神气,非常高贵。冰还没有全化,雪还没全消,白玉兰就已经长出了几个小小的芽苞,过了几天花就次第开放了,她们……爷爷是个老顽童写人作文爷爷是个出了名的老顽童,在我们村里,他爱说爱唱爱玩,算得上是个十八般武艺样样精通的新一代酷老头。在我心里,爷爷算得上最可亲的人了,我就喜欢爷爷的顽劲儿。这不,刚吃完饭,爷……饿了么留京过年洞察一人食小份菜小家庭套餐受热捧虎年春节留京怎么吃?北京青年报记者2月7日了解到,不少年轻人选择外卖服务增加留京过节的仪式感。饿了么平台显示,从除夕当天到初六期间,北京排名前五的外卖品类为:家乡地域美食、粥食……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网