记一次SQL优化。
Posted xiangerfer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次SQL优化。相关的知识,希望对你有一定的参考价值。
程序是数据库的用户,为打造良好的用户体验,我们一直在努力。
此次介绍一个基于SQL的数据库优化。SQL的优劣对数据库的性能影响非常关键。
查询只涉及如下表结构中的三个字段。如下
开发原始SQL
SELECT f002_ths043 AS ‘navDate‘, f003_ths043 AS ‘recentNav‘, f001_ths043 AS ‘fundCode‘ FROM ( SELECT info.*, @rn := IF(@pre = f001_ths043, @rn + 1, 1) AS rn, @pre := f001_ths043 FROM ( SELECT * FROM ths043 WHERE f001_ths043 IN ( ‘040008‘,‘050006‘,‘050106‘,‘150001‘,‘150002‘,‘150006‘,‘150007‘,‘150010‘,‘150011‘,‘162209‘,‘184688‘,‘184689‘,‘184690‘,‘184691‘,‘184692‘,‘184693‘,‘184695‘,‘184696‘,‘184698‘,‘184699‘,‘184700‘,‘184701‘,‘184702‘,‘184703‘,‘184705‘,‘184706‘,‘184708‘,‘184709‘,‘184710‘,‘184711‘,‘184712‘,‘184713‘,‘184718‘,‘184719‘,‘184720‘,‘184721‘,‘184722‘,‘184728‘,‘184738‘,‘200008‘,‘360007‘,‘500001‘,‘500002‘,‘500003‘,‘500005‘,‘500006‘,‘500007‘,‘500008‘,‘500009‘,‘500010‘,‘500011‘,‘500013‘,‘500015‘,‘500016‘,‘500017‘,‘500018‘,‘500019‘,‘500021‘,‘500025‘,‘500028‘,‘500029‘,‘500035‘,‘500038‘,‘500039‘,‘500056‘,‘500058‘,‘519694‘,‘590002‘,‘620001‘,‘CX0001‘,‘FB0001‘,‘J00023‘,‘J00108‘,‘J00112‘,‘J00117‘,‘J00118‘,‘J00120‘,‘J00127‘,‘J00128‘,‘J00130‘,‘J00141‘,‘J00144‘,‘J00149‘,‘J00153‘,‘J00154‘,‘J00164‘,‘J00246‘,‘J00327‘,‘J00328‘,‘J00329‘,‘J00330‘,‘J00331‘,‘J00332‘,‘J00333‘,‘J00334‘,‘J00335‘,‘J00336‘,‘J00337‘,‘J00338‘,‘J00339‘,‘J00340‘,‘J00341‘,‘J00342‘,‘J00343‘,‘J00344‘,‘J02337‘,‘J02338‘,‘J02339‘,‘J02340‘,‘J02341‘,‘J02342‘,‘J02343‘,‘J02344‘,‘J02345‘,‘J02346‘,‘J02347‘,‘J02349‘,‘J02350‘,‘J02351‘,‘J02352‘,‘J02353‘,‘J02354‘,‘J02355‘,‘J02356‘,‘J02357‘,‘J02358‘,‘J02359‘,‘J02360‘,‘J02361‘,‘J02362‘,‘J02363‘,‘J02364‘,‘J02365‘,‘J02366‘,‘J02367‘,‘J02368‘,‘J02369‘,‘J02370‘,‘J02371‘,‘J02372‘,‘J02373‘,‘J02374‘,‘J02375‘,‘J02376‘,‘J02377‘,‘J02378‘,‘J02540‘,‘J02541‘,‘J02542‘,‘J02550‘,‘J02551‘,‘J02552‘,‘J02553‘,‘J02554‘,‘J02555‘,‘J02556‘,‘J02557‘,‘J02558‘,‘J02559‘,‘J02560‘,‘J02561‘,‘J02562‘,‘J02563‘,‘J02564‘,‘J02565‘,‘J02566‘,‘J02567‘,‘J02568‘,‘J02569‘,‘J02570‘,‘J02571‘,‘J02573‘,‘J02575‘,‘J02576‘,‘J02577‘,‘J02579‘,‘J02580‘,‘J02581‘,‘J02583‘,‘J02584‘,‘J02585‘,‘J02586‘,‘J02587‘,‘J02588‘,‘J02589‘,‘J02590‘,‘J02591‘,‘J02592‘,‘J02593‘,‘J02595‘,‘J02596‘,‘J02597‘,‘J02598‘,‘J02599‘,‘J02600‘,‘J02601‘,‘J02602‘,‘J02603‘,‘J02604‘,‘J02605‘,‘J02606‘,‘J02607‘,‘J02608‘,‘J02609‘,‘J02610‘,‘J02611‘,‘J02612‘,‘J02613‘,‘J02614‘,‘J02615‘,‘J02616‘,‘J02617‘,‘J02618‘,‘J02619‘,‘J02620‘,‘J02621‘,‘J02622‘,‘J02623‘,‘J02624‘,‘J02625‘,‘J02626‘,‘J02627‘,‘J02629‘,‘J02630‘,‘J02631‘,‘J02632‘,‘J02633‘,‘J02634‘,‘J02635‘,‘J02636‘,‘J02637‘,‘J02638‘,‘J02639‘,‘J02640‘,‘J02641‘,‘J02642‘,‘J02643‘,‘J02644‘,‘J02647‘,‘J02650‘,‘J02651‘,‘J02652‘,‘J02653‘,‘J02654‘,‘J02657‘,‘J02658‘,‘J02692‘,‘J02701‘,‘J02705‘,‘J02715‘,‘J02717‘,‘J02718‘,‘J02722‘,‘J02723‘,‘J02724‘,‘J02725‘,‘J02727‘,‘J02728‘,‘J02729‘,‘J02730‘,‘J02737‘,‘J02740‘,‘J02741‘,‘J02744‘,‘KF0001‘,‘KF0002‘,‘KF0003‘,‘KF0004‘,‘KF0005‘,‘KF0006‘,‘KF0007‘,‘KF0008‘,‘KF0009‘,‘KF0010‘,‘KF0011‘,‘KF0012‘,‘KF0013‘,‘KF0014‘,‘KF0015‘,‘KF0016‘,‘KF0017‘,‘KF0018‘,‘KF0019‘,‘KF0020‘,‘KF0021‘,‘KF0022‘,‘KF0023‘,‘KF0024‘,‘KF0025‘,‘KF0026‘,‘KF0027‘,‘KF0028‘,‘KF0029‘,‘KF0030‘,‘KF0031‘,‘KF0032‘,‘KF0033‘,‘KF0034‘,‘KF0035‘,‘KF0036‘) AND f002_ths043 IS NOT NULL AND f003_ths043 IS NOT NULL ORDER BY f001_ths043, f002_ths043 DESC ) info JOIN (SELECT @rn := 0, @pre := 0) AS vars ) r WHERE rn = 1;
其目的为了寻找指定基金代码中,最后的价格。。
其实对于这种需求,在我个人角度来看,有很多中解决办法。
1、如果价格变更非常频繁,可以在应用层使用一张表记录当前(最后一次)价格,每次更新该表。附加一张记录表用于存储价格波动趋势。这样查询第一张表即可满足要求,速度相当快,收益比100%。
2、如果变更不频繁,可以将两张表合成一张。将一次查询的结果插入到一张新的临时表中,或者load进缓存,触发更新临时表,刷新缓存。由于更新不频繁,原表的数据查询也不会很频繁。多数情况下会查询临时表。
3、如果没有如果,就是想要效率高又省事,那么需要改写SQL。如下:(其中我将原本一个f001的索引,改成f001,f002,f003的复合索引。)
SELECT t1.*,t2.f003_ths043 FROM ( SELECT f001_ths043,max(f002_ths043) f002_ths043 FROM ths043 WHERE f001_ths043 IN ( ‘040008‘,‘050006‘,‘050106‘,‘150001‘,‘150002‘,‘150006‘,‘150007‘,‘150010‘,‘150011‘,‘162209‘,‘184688‘,‘184689‘,‘184690‘,‘184691‘,‘184692‘,‘184693‘,‘184695‘,‘184696‘,‘184698‘,‘184699‘,‘184700‘,‘184701‘,‘184702‘,‘184703‘,‘184705‘,‘184706‘,‘184708‘,‘184709‘,‘184710‘,‘184711‘,‘184712‘,‘184713‘,‘184718‘,‘184719‘,‘184720‘,‘184721‘,‘184722‘,‘184728‘,‘184738‘,‘200008‘,‘360007‘,‘500001‘,‘500002‘,‘500003‘,‘500005‘,‘500006‘,‘500007‘,‘500008‘,‘500009‘,‘500010‘,‘500011‘,‘500013‘,‘500015‘,‘500016‘,‘500017‘,‘500018‘,‘500019‘,‘500021‘,‘500025‘,‘500028‘,‘500029‘,‘500035‘,‘500038‘,‘500039‘,‘500056‘,‘500058‘,‘519694‘,‘590002‘,‘620001‘,‘CX0001‘,‘FB0001‘,‘J00023‘,‘J00108‘,‘J00112‘,‘J00117‘,‘J00118‘,‘J00120‘,‘J00127‘,‘J00128‘,‘J00130‘,‘J00141‘,‘J00144‘,‘J00149‘,‘J00153‘,‘J00154‘,‘J00164‘,‘J00246‘,‘J00327‘,‘J00328‘,‘J00329‘,‘J00330‘,‘J00331‘,‘J00332‘,‘J00333‘,‘J00334‘,‘J00335‘,‘J00336‘,‘J00337‘,‘J00338‘,‘J00339‘,‘J00340‘,‘J00341‘,‘J00342‘,‘J00343‘,‘J00344‘,‘J02337‘,‘J02338‘,‘J02339‘,‘J02340‘,‘J02341‘,‘J02342‘,‘J02343‘,‘J02344‘,‘J02345‘,‘J02346‘,‘J02347‘,‘J02349‘,‘J02350‘,‘J02351‘,‘J02352‘,‘J02353‘,‘J02354‘,‘J02355‘,‘J02356‘,‘J02357‘,‘J02358‘,‘J02359‘,‘J02360‘,‘J02361‘,‘J02362‘,‘J02363‘,‘J02364‘,‘J02365‘,‘J02366‘,‘J02367‘,‘J02368‘,‘J02369‘,‘J02370‘,‘J02371‘,‘J02372‘,‘J02373‘,‘J02374‘,‘J02375‘,‘J02376‘,‘J02377‘,‘J02378‘,‘J02540‘,‘J02541‘,‘J02542‘,‘J02550‘,‘J02551‘,‘J02552‘,‘J02553‘,‘J02554‘,‘J02555‘,‘J02556‘,‘J02557‘,‘J02558‘,‘J02559‘,‘J02560‘,‘J02561‘,‘J02562‘,‘J02563‘,‘J02564‘,‘J02565‘,‘J02566‘,‘J02567‘,‘J02568‘,‘J02569‘,‘J02570‘,‘J02571‘,‘J02573‘,‘J02575‘,‘J02576‘,‘J02577‘,‘J02579‘,‘J02580‘,‘J02581‘,‘J02583‘,‘J02584‘,‘J02585‘,‘J02586‘,‘J02587‘,‘J02588‘,‘J02589‘,‘J02590‘,‘J02591‘,‘J02592‘,‘J02593‘,‘J02595‘,‘J02596‘,‘J02597‘,‘J02598‘,‘J02599‘,‘J02600‘,‘J02601‘,‘J02602‘,‘J02603‘,‘J02604‘,‘J02605‘,‘J02606‘,‘J02607‘,‘J02608‘,‘J02609‘,‘J02610‘,‘J02611‘,‘J02612‘,‘J02613‘,‘J02614‘,‘J02615‘,‘J02616‘,‘J02617‘,‘J02618‘,‘J02619‘,‘J02620‘,‘J02621‘,‘J02622‘,‘J02623‘,‘J02624‘,‘J02625‘,‘J02626‘,‘J02627‘,‘J02629‘,‘J02630‘,‘J02631‘,‘J02632‘,‘J02633‘,‘J02634‘,‘J02635‘,‘J02636‘,‘J02637‘,‘J02638‘,‘J02639‘,‘J02640‘,‘J02641‘,‘J02642‘,‘J02643‘,‘J02644‘,‘J02647‘,‘J02650‘,‘J02651‘,‘J02652‘,‘J02653‘,‘J02654‘,‘J02657‘,‘J02658‘,‘J02692‘,‘J02701‘,‘J02705‘,‘J02715‘,‘J02717‘,‘J02718‘,‘J02722‘,‘J02723‘,‘J02724‘,‘J02725‘,‘J02727‘,‘J02728‘,‘J02729‘,‘J02730‘,‘J02737‘,‘J02740‘,‘J02741‘,‘J02744‘,‘KF0001‘,‘KF0002‘,‘KF0003‘,‘KF0004‘,‘KF0005‘,‘KF0006‘,‘KF0007‘,‘KF0008‘,‘KF0009‘,‘KF0010‘,‘KF0011‘,‘KF0012‘,‘KF0013‘,‘KF0014‘,‘KF0015‘,‘KF0016‘,‘KF0017‘,‘KF0018‘,‘KF0019‘,‘KF0020‘,‘KF0021‘,‘KF0022‘,‘KF0023‘,‘KF0024‘,‘KF0025‘,‘KF0026‘,‘KF0027‘,‘KF0028‘,‘KF0029‘,‘KF0030‘,‘KF0031‘,‘KF0032‘,‘KF0033‘,‘KF0034‘,‘KF0035‘,‘KF0036‘) GROUP BY f001_ths043 ) t1 LEFT JOIN ths043 t2 ON t1.f001_ths043=t2.f001_ths043 AND t1.f002_ths043 = t2.f002_ths043 ;
由原来8S提速到0.07s。对于SQL的优化就是如此立竿见影,也应当如此。
但是,并非每条SQL都可以优化,如果业务就是想要查单表中的1000万条记录,没有任何逻辑,条件等。。这种SQL在数据库层的优化效率提升微乎其微。相反,业务逻辑层的优化成效很大。
以上优化过程使用到了很多关于数据库内部的特性。如需交流,或者有更好意见,qq 475982055
千万不可写成以下这种。虽说条条路可以通罗马,但愿不要经过西天。
SELECT * FROM ( SELECT a.f001_ths043, a.f002_ths043, a.f003_ths043, ( SELECT count(*) FROM ths043 b WHERE a.f002_ths043 <= b.f002_ths043 AND a.f001_ths043 = b.f001_ths043 ) AS row_number FROM ths043 a ) a WHERE a.row_number = 1; ;
以上是关于记一次SQL优化。的主要内容,如果未能解决你的问题,请参考以下文章