首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > oracle >

关于Oracle10g里的Order by速度慢的有关问题

2013-07-04 
【求助】【急】关于Oracle10g里的Order by速度慢的问题表结构:CREATE TABLE TB_RID_TRACE_2013(IDVARCHAR2(50)

【求助】【急】关于Oracle10g里的Order by速度慢的问题
表结构:
CREATE TABLE TB_RID_TRACE_2013
(
  ID             VARCHAR2(50) NOT NULL CONSTRAINT PK_TB_RID_TRACE_2013 PRIMARY KEY,
  SESSION_ID     VARCHAR2(50),
  LOGIN_AT       DATE,
  LOGOUT_AT      DATE,
  ID_TYPE        VARCHAR2(32),
  ID_CODE        VARCHAR2(100),
  ID_NAME        VARCHAR2(100),
  AREA_CODE      VARCHAR2(15),
  SERVICE_CODE   VARCHAR2(32),
  SERVICE_WAN_IP VARCHAR2(32),
  SERVICE_LAN_IP VARCHAR2(32),
  SERVICE_MAC    VARCHAR2(32),
  HOST_NAME      VARCHAR2(100)
)
PARTITION BY RANGE (LOGIN_AT)
(
PARTITION TB_RID_TRACE_2013_PART_01 VALUES LESS THAN (TO_DATE('2013-02-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_02 VALUES LESS THAN (TO_DATE('2013-03-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_03 VALUES LESS THAN (TO_DATE('2013-04-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_04 VALUES LESS THAN (TO_DATE('2013-05-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_05 VALUES LESS THAN (TO_DATE('2013-06-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_06 VALUES LESS THAN (TO_DATE('2013-07-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_07 VALUES LESS THAN (TO_DATE('2013-08-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_08 VALUES LESS THAN (TO_DATE('2013-09-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_09 VALUES LESS THAN (TO_DATE('2013-10-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_10 VALUES LESS THAN (TO_DATE('2013-11-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_11 VALUES LESS THAN (TO_DATE('2013-12-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
PARTITION TB_RID_TRACE_2013_PART_12 VALUES LESS THAN (TO_DATE('2014-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'))


)
NOLOGGING;

该表上创建的索引:
CREATE INDEX IDX_2013_ID_CODE ON TB_RID_TRACE_2013 (ID_CODE DESC);

CREATE INDEX IDX_2013_LOGIN_AT ON TB_RID_TRACE_2013 (LOGIN_AT DESC);

CREATE INDEX IDX_2013_LOGOUT_AT ON TB_RID_TRACE_2013 (LOGOUT_AT DESC);

CREATE INDEX IDX_2013_SERVICE_CODE ON TB_RID_TRACE_2013 (SERVICE_CODE DESC);


目前表里有18000000条数据,系统里是使用ExtJS分页显示列表。问题是执行普通SQL速度很快。但是如果SQL里包含Order By后速度就变得爆慢。以下是我执行的SQL和时间以及执行计划的内容:

SQL1,执行时间:0.172秒100条数据
SELECT * FROM TB_RID_TRACE_2013 T WHERE T.LOGIN_AT BETWEEN TO_DATE('2013-06-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE('2013-06-15 00:00:00', 'YYYY-MM-DD HH24:MI:SS');

SQL1执行计划:
执行计划
----------------------
Plan hash value: 3349134993

------------------------------------------------------------------------
| Id  | Operation              | Name              | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |                   |  1555K|   255M| 19128   (2)| 00:03:50 |       |    |
|   1 |  PARTITION RANGE SINGLE|                   |  1555K|   255M| 19128   (2)| 00:03:50 |     6 |  6 |
|*  2 |   TABLE ACCESS FULL    | TB_RID_TRACE_2013 |  1555K|   255M| 19128   (2)| 00:03:50 |     6 |  6 |
------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("T"."LOGIN_AT"<=TO_DATE('2013-06-15 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))




SQL2,执行时间:14.789秒100条数据
SELECT T.* FROM TB_RID_TRACE_2013 T WHERE T.LOGIN_AT BETWEEN TO_DATE('2013-06-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE('2013-06-15 00:00:00', 'YYYY-MM-DD HH24:MI:SS') ORDER BY T.LOGIN_AT;

SQL2执行计划:
执行计划
----------------------
Plan hash value: 2801453287

--------------------------------------------
| Id  | Operation              | Name              | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------
|   0 | SELECT STATEMENT       |                   |  1555K|   255M|       | 78265   (1)| 00:15:40 |    |          |
|   1 |  PARTITION RANGE SINGLE|                   |  1555K|   255M|       | 78265   (1)| 00:15:40 |  6 |        6 |
|   2 |   SORT ORDER BY        |                   |  1555K|   255M|   607M| 78265   (1)| 00:15:40 |    |          |
|*  3 |    TABLE ACCESS FULL   | TB_RID_TRACE_2013 |  1555K|   255M|       | 19128   (2)| 00:03:50 |  6 |        6 |
--------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------



   3 - filter("T"."LOGIN_AT"<=TO_DATE('2013-06-15 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))

SQL3,执行时间:24.492秒100条数据
SELECT * FROM (SELECT ROWNUM RN, T.* FROM TB_RID_TRACE_2013 T WHERE T.LOGIN_AT BETWEEN TO_DATE('2013-06-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE('2013-06-15 00:00:00', 'YYYY-MM-DD HH24:MI:SS') ORDER BY T.LOGIN_AT DESC) T2 WHERE T2.RN BETWEEN 0 AND 100;

SQL3执行计划:
执行计划
----------------------
Plan hash value: 283752969

-----------------------------------------------
| Id  | Operation                 | Name              | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
-----------------------------------------------
|   0 | SELECT STATEMENT          |                   |  1555K|   504M|       | 78265   (1)| 00:15:40 |       |       |
|*  1 |  VIEW                     |                   |  1555K|   504M|       | 78265   (1)| 00:15:40 |       |       |
|   2 |   SORT ORDER BY           |                   |  1555K|   255M|   607M| 78265   (1)| 00:15:40 |       |       |
|   3 |    COUNT                  |                   |       |       |       |            |          |       |       |


|   4 |     PARTITION RANGE SINGLE|                   |  1555K|   255M|       | 19128   (2)| 00:03:50 |     6 |     6 |
|*  5 |      TABLE ACCESS FULL    | TB_RID_TRACE_2013 |  1555K|   255M|       | 19128   (2)| 00:03:50 |     6 |     6 |
-----------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("T2"."RN"<=100 AND "T2"."RN">=0)
   5 - filter("T"."LOGIN_AT"<=TO_DATE('2013-06-15 00:00:00', 'yyyy-mm-dd hh24:mi:ss')) Oracle10g Order?by 速度慢 优化 索引
[解决办法]
TO_DATE('2013-06-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE('2013-06-15 00:00:00', 'YYYY-MM-DD HH24:MI:SS');
为条件返回多少条记录?从查询计划上看返回1555K
真实有那么多吗?看看是否要收集一些统计信息?
[解决办法]
从执行计划大体可以得出:
1)5 - filter("T"."LOGIN_AT"<=TO_DATE('2013-06-15 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))
   ==> 存在隐式类型转换!太槽糕了
2)  2 
[解决办法]
   TABLE ACCESS FULL    
[解决办法]
 TB_RID_TRACE_2013 
   ==> CBO选择全表扫、索引在这里不起作用
3)既然分区了、干嘛还选择全局索引?
4)1  sorts (disk)
   ==> 都跑到磁盘上来排序了?pga里面sort_area多大?
5)索引是我后来追加的,当时表里已经有这么多数据了,我也REBUILD了啊!


   ==> 表和索引的统计信息重新收集了没?

热点排行