《Oracle查询优化改写技巧与案例》不讲具体语法,只是以案例的形式介绍各种查询语句的用法。
《Oracle查询优化改写技巧与案例》第1~4章是基础部分,讲述了常用的各种基础语句,以及常见的错误和正确语句的写法。这部分的内容应熟练掌握,因为日常查询和优化改写都要用到。
《Oracle查询优化改写技巧与案例》第5~12章是提高部分,讲解了正则表达式、分析函数、树形查询及汇总函数的用法。这部分知识常用于对一些复杂需求的实现及优化改写。
《Oracle查询优化改写技巧与案例》最后两章介绍日常的优化改写案例。这部分是前面所学知识的扩展应用。
14.19 整理优化分页语句
网友说有一个语句查询需要1秒多,希望能优化。于是让网友先把语句发过来,一看到语句,笔者就惊呆了:
SELECT *
FROM (SELECT a.*, ROWNUM NUM
FROM (SELECT *
FROM b
WHERE 1 = 1
AND type = '10'
AND s_cd = '1000'
AND name LIKE '%xxx%'
ORDER BY (SELECT NVL(TO_NUMBER(REPLACE(TRANSLATE(des, REPLACE(TRANSLATE(des, '0123456789', '##########'), '#', ''), RPAD('#', 20, '#')), '#', '')), '0')
FROM b_PRICE B
WHERE max_price = '1'
AND B.id = b.id),
name) a)
WHERE NUM > 1 AND NUM <= 20
这个ORDER BY需要全表扫描才能得到所需数据,而且函数嵌套了多层,不好处理。因为上面这个替换语句的目的是只保留字符串中的数字,于是笔者给他提供了一个正则:
ORDER BY regexp_replace(des, '[^0-9]', '')
这个语句确认结果后,把语句改成了10.1节中讲过的样式:
SELECT *
FROM (SELECT a.*, rownum num
FROM (SELECT a.*
FROM b a
INNER JOIN b_price b ON (b.id = a.id)
WHERE 1 = 1
AND b.max_price = '1'
AND a.type = '10'
AND a.s_cd = '1000'
AND a.name LIKE '%xxx%'
ORDER BY regexp_replace(des, '[^0-9]', '')) a
WHERE num <= 20)
WHERE num > 1;
注意上面两个分页条件的位置,这样更改后,把过滤列与regexp_replace(des, '[^0-9]', '')一起放在组合索引里,优化就到此结束
……
——国内知名专家白鳝
★当教主告诉我他准备写一本有关SQL编程改写的书时,我非常高兴,感觉到将会有一大批开发人员可以借助这样一本书使自己的SQL水平提升一个层次。因为我知道这不是一本SQL入门的书,也不是一本专门讲优化理论的SQL优化书籍,而是一本结合常见的开发场景介绍编程技巧的书籍。
——资深Oracle培训人员黄超(网名:道道)