前几天, 一个用户找到我, 说查一个小表的时候非常慢, 我问有多慢, 他说最快也得半个小时才能出结果, 有时干脆不出结果, 我说小表多大, 他说就几十兆, 有点疑惑, 让他帮忙获取了相关信息, 一看就明白了, 原来所谓的小表是假的, 下面是分析时参照的信息及分析的步骤
SQL 语句:
select * from t_rec where rec_date>trunc(sysdate-1);
SQL 计划:
- ------------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
- ------------------------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 2011 | 318K| 892 (3)| 00:00:13 | | |
- | 1 | PARTITION RANGE ITERATOR| | 2011 | 318K| 892 (3)| 00:00:13 | KEY | 21 |
- |* 2 | TABLE ACCESS FULL | T_REC | 2011 | 318K| 892 (3)| 00:00:13 | KEY | 21 |
- ------------------------------------------------------------------------------------------------------------
表所占空间:
- select sum(bytes)/1024/1024 "(MB)" from dba_extents where segment_name='T_REC';
- (MB)
- ----------
- 38.675
看到这里, 我有点疑惑, 表确实不大, 但有个线索, 大家注意到没有, 那就是 partition, 如此小的表, 有必要分区吗? 莫非
desc t_rec
名称 是否为空? 类型
- ----------------------------------------- -------- ----------------------------
- REC_ID NOT NULL VARCHAR2(20)
- REC_NAME VARCHAR2(200)
- REC_DESC CLOB
- REC_DATE NOT NULL DATE
- REC_CLASS NUMBER
- REC_LEN NUMBER
至此, 真相大白了, 大家明白了吧? 也许有的同学还是不明白, 继续
- select sum(bytes)/1024/1024/1024 "(GB)" from dba_extents
- where partition_name in(
- select lob_partition_name from user_lob_partitions
- where table_name='T_REC');
- (GB)
- ----------
- 309.31425
明白了吗? 呵呵, 现在通过上面的信息, 我们找到了小表超慢的原因, 但这时, 用户再次提出: 我们怎么解决这个查询慢的问题呢? 继续
- select index_name,table_name,column_name from user_ind_columns where table_name='T_REC'
- INDEX_NAME TABLE_NAME COLUMN_NAME
- ------------------------------ ------------------------------ ----------------------------------------
- IDX1_REC_DATE T_REC REC_DATE
- IDX2_REC_ID T_REC REC_ID
因为该库为用户生产库, 且该表较大, 所以, 决定先通过 hint 测试效率问题:
- select /*+ index(t IDX1_REC_DATE)*/* from t_rec t where rec_date>trunc(sysdate-1);
加 hint 后计划:
- ---------------------------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
- ---------------------------------------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 2011 | 318K| 912 (1)| 00:00:15 | | |
- | 1 | PARTITION RANGE ITERATOR | | 2011 | 318K| 912 (1)| 00:00:15 | KEY | 21 |
- | 2 | TABLE ACCESS BY LOCAL INDEX ROWID| T_REC | 2011 | 318K| 912 (1)| 00:00:15 | KEY | 21 |
- |* 3 | INDEX RANGE SCAN | IDX1_REC_DATE| 2011 | | 14 (0)| 00:00:01 | KEY | 21 |
hint 生效, 测试 2 秒出结果, 征求用户意见, 用户说这样可以, 至此问题解决, 大家可以参照学习, 禁止转载
来源: https://www.cnblogs.com/lhdz_bj/p/8681492.html