首页 > 数据库 > 数据库开发技术 > 一次sql语句优化的反思
5.1节前现网反馈数据库性能很低下,statspack报告发回来后top 5
的两个突出的sql语句如下:
1、SELECT COUNT(*)
FROM (SELECT t0.id,
t0.parentid,
t0.path,
t0.TYPE,
t5.NAME,
t5.catename,
t5.icpcode,
t5.icpservid,
t5.spname,
t5.auditionurl,
t5.downloadurl,
t5.createdate,
t5.expire,
t5.coloringprice,
t5.singer,
t5.special,
t5.editontype,
t5.contenttag,
t5.audiotype,
t5.gameinfourl,
t5.imagename,
t5.servdesc,
t5.chargetype,
t5.price,
t5.accessmodeid,
t5.paymode,
t5.downloadtimes,
t5.nameletter
FROM t_r_base t0, v_gcontent t5
WHERE t0.TYPE LIKE '
AND t5.id = t0.id
AND t0.TYPE = '
AND EXISTS (SELECT 1
FROM t_r_base opt0, t_r_reference t4
WHERE opt0.TYPE LIKE '
AND t4.id = opt0.id
AND opt0.path LIKE '
AND t0.id = refnodeid)
ORDER BY t5.downloadtimes DESC);
2、SELECT t0.id,
t0.parentid,
t0.path,
t0.TYPE,
t5.NAME,
t5.catename,
t5.icpcode,
t5.icpservid,
t5.spname,
t5.auditionurl,
t5.downloadurl,
t5.createdate,
t5.expire,
t5.coloringprice,
t5.singer,
t5.special,
t5.editontype,
t5.contenttag,
t5.audiotype,
t5.gameinfourl,
t5.imagename,
t5.servdesc,
t5.chargetype,
t5.price,
t5.accessmodeid,
t5.paymode,
t5.downloadtimes,
t5.nameletter
FROM t_r_base t0, v_gcontent t5
WHERE t0.TYPE LIKE '
AND t5.id = t0.id
AND t0.TYPE = '
AND EXISTS (SELECT 1
FROM t_r_base opt0, t_r_reference t4
WHERE opt0.TYPE LIKE '
AND t4.id = opt0.id
AND opt0.path LIKE '
AND t0.id = refnodeid)
ORDER BY t5.downloadtimes DESC;
其中v_gcontent是个庞大的普通视图。
该语句发生在用户每次高级搜索时执行,对应的分析结果如下:
CPU Elapsd
Buffer Gets Executions Gets per Exec %Total Time (s) Time (s) Hash Value
--------------- ------------ -------------- ------ -------- --------- ----------
225,840,266 95 2,377,266.0 11.1 0.00 6939.53 2689214047
Module: JDBC Thin Client
select t0.id,t0.parentID,t0.path,t0.type,t5.name,t5.cateName,t5.
icpCode,t5.icpServId,t5.spName,t5.auditionUrl,t5.downLoadUrl,t5.
createDate,t5.expire,t5.coloringPrice,t5.singer,t5.special,t5.ed
itonType,t5.contentTag,t5.audioType,t5.gameInfoUrl,t5.imageName,
t5.SERVDESC,t5.CHARGETYPE,t5.PRICE,t5.ACCESSMODEID,t5.PAYMODE,t5
共2,377,266.0个块,总共拿了2,377,266次,包括重复的块读,可见数据是惊人的。
下面是具体的优化细节:
1、在求count时没必要order by,导致排序的记录多时产生大量的buffer和IO;
2、将FROM后语句改写为表关联,不用EXISTS;
3、t0.TYPE LIKE '是完全多余的条件;
4、将v_gcontent这个庞大的普通视图改为实体化视图并创建索引。
经过上述的优化问题得到解决!
由此给广大的数据库程序开发者和系统设计架构者一些建议,如下:
1、少用嵌套,层次复杂,功能冗余的sql查询语句,多用简单的经过分解或中间转化的sql查询语句;
2、少用子查询(in,exists,not in,not exists等)多用表关联,充分利用表与表之间的索引;
3、普通视图就是一个子查询,每次select视图都是一次子查询;而实体化视图就不一样,它本身就是一张表,有自己的物理存储和索引,性能上比普通视图高。在报表,查询等功能上建议多用;
4、从应用角度上出发,对于一些门户级平台级的系统,并发访问高,强烈不建议每一次访问都去跟数据库交互,这样会把数据库给搞塌掉,建议采用应用级上的数据缓存或本地数据文件形式来提高性能。
[@more@]来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/38542/viewspace-913980/ ,如需转载,请注明出处,否则将追究法律责任。