背景

开发说:

有段SQL语句,去掉order by很快,有order by之后,查询1小时都无法返回结果。

我叫他把SQL扔给我看下。

SQL代码及执行计划

select *
from (select d.*, rownum as num
from (SELECT A.BILLNO,
A.BILLCODE,
A.GETDATE,
A.GETUNITCODE,
A.GETCODE,
A.GETORGANCODE,
A.USEORGANCODE,
A.USEDATE,
A.USEUNITCODE,
A.USERCODE,
A.CURRENCYCODE,
A.AMOUNT,
A.NAME,
A.NOTES,
A.STATUSCODE,
A.IFPAGEONHOLE,
A.OPCODE,
A.OPUNITCODE,
A.OPDATE,
A.LOCKTIME,
A.GETAGENTCODE,
(SELECT D.AGENTNAME
FROM SYN_MM_AGENTCODE_TC D
WHERE D.AGENTCODE = A.GETAGENTCODE) AS GETAGENTNAME,
A.USEAGENTCODE,
A.OUTSTATUS,
CASE A.BILLCODE
WHEN 'B2010005' THEN
A.FACTBILLCODE
ELSE
''
END FACTBILLCODE,
A.SALES,
A.FROMDATE,
A.TODATE,
(SELECT BILLNAME
FROM BD_BILLCODE
WHERE BILLCODE = A.BILLCODE) BILLNAME,
(SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.USERCODE) USERNAME,
(SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.GETCODE) GETERNAME,
(SELECT NO3
FROM B_BILLDETAIL
WHERE BILLNO = A.BILLNO
AND BILLCODE = A.BILLCODE
AND FACTBILLCODE = A.FACTBILLCODE) ONLINEINVOICENO,
(SELECT NO4
FROM B_BILLDETAIL
WHERE BILLNO = A.BILLNO
AND BILLCODE = A.BILLCODE
AND FACTBILLCODE = A.FACTBILLCODE) ONLINEINVOICECODE
FROM B_BILL A
WHERE 3 > 2
AND (3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2)
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND ((TRIM(GETUNITCODE) = '013100' OR
GETAGENTCODE IN
(SELECT DISTINCT A.AGENTCODE
FROM CIOD_IM.CHAGENTBASE A
WHERE 1 = 1
AND TRIM(A.BRANCHCODE) = '013100')))
ORDER BY A.BILLNO) d
where rownum <= 100)
where num > 0
; Plan hash value: 677599094 --------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 27792 | 11 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | CHAGENTBASE | 1 | 56 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_CHAGENTBASE_TEST | 1 | | 1 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID | BD_BILLCODE | 1 | 31 | 1 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN | PK_BD_BILLCODE | 1 | | 0 (0)| 00:00:01 |
| 5 | TABLE ACCESS BY INDEX ROWID | T_EMPLOYEE_VIEW | 1 | 26 | 2 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | IND_T_EMPLOYEE_VIEW | 1 | | 1 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID | T_EMPLOYEE_VIEW | 1 | 26 | 2 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | IND_T_EMPLOYEE_VIEW | 1 | | 1 (0)| 00:00:01 |
| 9 | TABLE ACCESS BY INDEX ROWID | B_BILLDETAIL | 1 | 50 | 4 (0)| 00:00:01 |
|* 10 | INDEX RANGE SCAN | PK_B_BILLDETAIL_02 | 1 | | 3 (0)| 00:00:01 |
| 11 | TABLE ACCESS BY INDEX ROWID | B_BILLDETAIL | 1 | 50 | 4 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | PK_B_BILLDETAIL_02 | 1 | | 3 (0)| 00:00:01 |
|* 13 | VIEW | | 6 | 27792 | 11 (0)| 00:00:01 |
|* 14 | COUNT STOPKEY | | | | | |
| 15 | VIEW | | 6 | 27714 | 11 (0)| 00:00:01 |
|* 16 | FILTER | | | | | |
| 17 | TABLE ACCESS BY INDEX ROWID| B_BILL | 56M| 10G| 11 (0)| 00:00:01 |
| 18 | INDEX FULL SCAN | PK_B_BILL_01 | 100 | | 4 (0)| 00:00:01 |
|* 19 | TABLE ACCESS BY INDEX ROWID| CHAGENTBASE | 1 | 15 | 2 (0)| 00:00:01 |
|* 20 | INDEX RANGE SCAN | IDX_CHAGENTBASE_TEST | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("D"."AGENTCODE"=:B1)
4 - access("BILLCODE"=:B1)
6 - access("A"."CODE"=:B1)
8 - access("A"."CODE"=:B1)
10 - access("BILLNO"=:B1 AND "BILLCODE"=:B2 AND "FACTBILLCODE"=:B3)
12 - access("BILLNO"=:B1 AND "BILLCODE"=:B2 AND "FACTBILLCODE"=:B3)
13 - filter("NUM">0)
14 - filter(ROWNUM<=100)
16 - filter(TRIM("GETUNITCODE")='013100' OR EXISTS (SELECT /*+ */ 0 FROM
"CIOD_IM"."CHAGENTBASE" "A" WHERE "A"."AGENTCODE"=:B1 AND TRIM("A"."BRANCHCODE")='013100'))
19 - filter(TRIM("A"."BRANCHCODE")='013100')
20 - access("A"."AGENTCODE"=:B1)

优化

1)建立索引

create index IDX_B_BILL_TEST03 on B_BILL (GETAGENTCODE, BILLNO);

2)添加hint

/*+index_rs(a)*/

3)or改写成union

select *
from (select d.*, rownum as num
from (SELECT /*+index_rs(a)*/
A.BILLNO,
A.BILLCODE,
A.GETDATE,
A.GETUNITCODE,
A.GETCODE,
A.GETORGANCODE,
A.USEORGANCODE,
A.USEDATE,
A.USEUNITCODE,
A.USERCODE,
A.CURRENCYCODE,
A.AMOUNT,
A.NAME,
A.NOTES,
A.STATUSCODE,
A.IFPAGEONHOLE,
A.OPCODE,
A.OPUNITCODE,
A.OPDATE,
A.LOCKTIME,
A.GETAGENTCODE,
(SELECT D.AGENTNAME
FROM SYN_MM_AGENTCODE_TC D
WHERE D.AGENTCODE = A.GETAGENTCODE) AS GETAGENTNAME,
A.USEAGENTCODE,
A.OUTSTATUS,
CASE A.BILLCODE
WHEN 'B2010005' THEN
A.FACTBILLCODE
ELSE
''
END FACTBILLCODE,
A.SALES,
A.FROMDATE,
A.TODATE,
(SELECT BILLNAME FROM BD_BILLCODE WHERE BILLCODE = A.BILLCODE) BILLNAME,
(SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.USERCODE) USERNAME,
(SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.GETCODE) GETERNAME,
(SELECT NO3
FROM B_BILLDETAIL
WHERE BILLNO = A.BILLNO
AND BILLCODE = A.BILLCODE
AND FACTBILLCODE = A.FACTBILLCODE) ONLINEINVOICENO,
(SELECT NO4
FROM B_BILLDETAIL
WHERE BILLNO = A.BILLNO
AND BILLCODE = A.BILLCODE
AND FACTBILLCODE = A.FACTBILLCODE) ONLINEINVOICECODE
FROM B_BILL A
WHERE 3 > 2
AND (3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2)
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND ((TRIM(GETUNITCODE) = '013100' /*OR
GETAGENTCODE IN
(SELECT A.AGENTCODE
FROM CIOD_IM.CHAGENTBASE A
WHERE 1 = 1
AND TRIM(A.BRANCHCODE) = '013100')*/
))
union
SELECT A.BILLNO,
A.BILLCODE,
A.GETDATE,
A.GETUNITCODE,
A.GETCODE,
A.GETORGANCODE,
A.USEORGANCODE,
A.USEDATE,
A.USEUNITCODE,
A.USERCODE,
A.CURRENCYCODE,
A.AMOUNT,
A.NAME,
A.NOTES,
A.STATUSCODE,
A.IFPAGEONHOLE,
A.OPCODE,
A.OPUNITCODE,
A.OPDATE,
A.LOCKTIME,
A.GETAGENTCODE,
(SELECT D.AGENTNAME
FROM SYN_MM_AGENTCODE_TC D
WHERE D.AGENTCODE = A.GETAGENTCODE) AS GETAGENTNAME,
A.USEAGENTCODE,
A.OUTSTATUS,
CASE A.BILLCODE
WHEN 'B2010005' THEN
A.FACTBILLCODE
ELSE
''
END FACTBILLCODE,
A.SALES,
A.FROMDATE,
A.TODATE,
(SELECT BILLNAME
FROM BD_BILLCODE
WHERE BILLCODE = A.BILLCODE) BILLNAME,
(SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.USERCODE) USERNAME,
(SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.GETCODE) GETERNAME,
(SELECT NO3
FROM B_BILLDETAIL
WHERE BILLNO = A.BILLNO
AND BILLCODE = A.BILLCODE
AND FACTBILLCODE = A.FACTBILLCODE) ONLINEINVOICENO,
(SELECT NO4
FROM B_BILLDETAIL
WHERE BILLNO = A.BILLNO
AND BILLCODE = A.BILLCODE
AND FACTBILLCODE = A.FACTBILLCODE) ONLINEINVOICECODE
FROM B_BILL A
WHERE 3 > 2
AND (3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2 OR 3 > 2)
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND (( /*TRIM(GETUNITCODE) = '013100' OR*/
GETAGENTCODE IN
(SELECT A.AGENTCODE
FROM CIOD_IM.CHAGENTBASE A
WHERE 1 = 1
AND TRIM(A.BRANCHCODE) = '013100')))
ORDER BY BILLNO) d
where rownum <= 100)
where num > 0; Plan hash value: 215809904 --------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 452K| | 76511 (34)| 00:15:19 |
|* 1 | VIEW | | 100 | 452K| | 76511 (34)| 00:15:19 |
|* 2 | COUNT STOPKEY | | | | | | |
| 3 | VIEW | | 570K| 2511M| | 76511 (34)| 00:15:19 |
|* 4 | SORT UNIQUE STOPKEY | | 570K| 104M| 278M| 50812 (46)| 00:10:10 |
| 5 | UNION-ALL | | | | | | |
| 6 | TABLE ACCESS BY INDEX ROWID| B_BILL | 569K| 104M| | 3755 (1)| 00:00:46 |
|* 7 | INDEX RANGE SCAN | IDX_B_BILL_TEST | 227K| | | 771 (1)| 00:00:10 |
| 8 | TABLE ACCESS BY INDEX ROWID| B_BILL | 81 | 15552 | | 7742 (1)| 00:01:33 |
| 9 | NESTED LOOPS | | 262 | 54234 | | 23093 (1)| 00:04:38 |
|* 10 | TABLE ACCESS FULL | CHAGENTBASE | 3 | 45 | | 6 (0)| 00:00:01 |
|* 11 | INDEX RANGE SCAN | IDX_B_BILL_TEST03 | 1089 | | | 7672 (1)| 00:01:33 |
-------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("NUM">0)
2 - filter(ROWNUM<=100)
4 - filter(ROWNUM<=100)
7 - access(TRIM("GETUNITCODE")='013100')
10 - filter(TRIM("A"."BRANCHCODE")='013100')
11 - access("GETAGENTCODE"="A"."AGENTCODE")
filter("GETAGENTCODE" IS NOT NULL)

优化后

1s能返回结果,性能大大提升。开发很开心地把SQL拿走了。

分页语句where条件中的子查询有or关键字优化的更多相关文章

  1. 在MySQL中使用子查询

    子查询作为数据源 子查询生成的结果集包含行.列数据,因而非常适合将它与表一起包含在from子句的子查询里.例: SELECT d.dept_id, d.name, e_cnt.how_many num ...

  2. 在 SQL Server 数据库的 WHERE 语句中使用子查询

    这是关于子查询语句的一系列文章中的第三篇.在这篇文章中我们将讨论WHERE语句中的子查询语句.其他的文章讨论了其他语句中的子查询语句. 本次课程中的所有例子都是基于Microsoft SQL Serv ...

  3. 在update语句中使用子查询

    在update 中的 where 子句中使用子查询: UPDATE mg_page_log as a  SET  page_num=1 WHERE id in( SELECT id  from mg_ ...

  4. 分享一篇:sql语句中使用子查询,可能会引起查询的性能问题,查询时间会变长

    前段时间,做自动化适配的时候,查找需要的数据的时候,使用到了dblink,跨数据库实例进行访问,整段sql拼接再加上dblink,在plsql查询的时候,性能还不是很长时间,最多2分钟可以查到,前期调 ...

  5. 详细讲述MySQL中的子查询操作 (来自脚本之家)

    继续做以下的前期准备工作: 新建一个测试数据库TestDB: ? 1 create database TestDB; 创建测试表table1和table2: ? 1 2 3 4 5 6 7 8 9 1 ...

  6. sql语句增删改查与子查询

    修改表 修改表 语法: Alter table <旧表名> rename [ TO] <新表名>; 例子:Alter table `demo01` rename `demo02 ...

  7. mysql 在update中实现子查询的方式

    当使用mysql条件更新时--最先让人想到的写法 UPDATE buyer SET is_seller=1 WHERE uid IN (SELECT uid FROM seller) 此语句是错误的, ...

  8. SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  9. update 中实现子查询

    mysql 在update中实现子查询的方式   当使用mysql条件更新时--最先让人想到的写法 UPDATE buyer SET is_seller=1 WHERE uid IN (SELECT  ...

随机推荐

  1. thinkphp5升级版开源框架tpframe v2.1发布

    免费开源框架tpframe是一款以thinkphp5为驱动,在此基础上进行进一步的完善与改进的框架,保持了ThinkPHP5原有的所有特性,优化核心,减少依赖,为个人或企业建站提供高效.快速解决的方案 ...

  2. MySQL `explicit_defaults_for_timestamp` 与 TIMESTAMP

    考察下面的 SQL 脚本: CREATE TABLE test1( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, data VARCHAR(20), ts1 ...

  3. Oracle 单引号与双引号的区别

    双引号一般是用来转义的,如果alias里面有空格或其它保留符号,必须使用双引号.而单引号是用来特制的,比如字符串的引用,日期字符串的引用,都必须包括在单引号中,可以参与运算或其它表达式中.两者不可混用 ...

  4. Jquery | 基础 | jQuery表单对象属性过滤选择器

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>使用jQuery表单对象属性 ...

  5. HDU - 6058 Kanade's sum

    Bryce1010模板 http://acm.hdu.edu.cn/showproblem.php?pid=6058 /* 思路是:找出每个x为第k大的区间个数有多少 用pos[i]保存当前x的位置, ...

  6. MyBatsi-Mapper映射文件

    Mapper映射文件 cache – 给定命名空间的缓存配置. cache-ref – 其他命名空间缓存配置的引用. resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加 ...

  7. 非常强大的前端插件:emmet

    安装 Emmet 也有快速生成文件头的功能啊,而且更强大啊输入下边加粗的缩写,然后Tab,就OK了啊http://docs.emmet.io/cheat-sheet/ html:4t <!DOC ...

  8. P1320 压缩技术(续集版)

    题目描述 设某汉字由N X N的0和1的点阵图案组成,如下图.我们依照以下规则生成压缩码.连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从上到下,由左到右.第一个数表示连续有几个0 ...

  9. AJPFX谈Java 性能优化之基本类型 vs 引用类型

    ★名词定义 先明确一下什么是“基本类型”,什么是“引用类型”. 简单地说,所谓基本类型就是 Java 语言中如下的8种内置类型: booleancharbyteshortintlongfloatdou ...

  10. Chrome插件制作

    由于网上很难找到关于Chrome插件制作的中文教程,为了总结和方便更多的开发者,本文以最常见的显示效果为browser_action的二维码插件为例,进行相关阐述.前端童鞋开发的话应该很简单的,鄙人是 ...