[20130319]一条sql语句的优化.txt

[20130319]一条sql语句的优化.txt

生产系统,遇到这样一条语句:
SELECT MAX (LENGTH (pe_id)) FROM pe_master_index WHERE SUBSTR (pe_id, 1, 2) = 'TJ';

--真不知道开发人员如何想的,写出这样的语句.字段pe_id是主键.
--数据库版本

SQL> select * from v$version where rownum
BANNER                                                          
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
1 row selected.
SQL> SELECT MAX (LENGTH (pe_id)) FROM pe_master_index WHERE SUBSTR (pe_id, 1, 2) = 'TJ';
MAX(LENGTH(PE_ID))
------------------
                10

SQL> @dpc ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  awfcmwrca41fc, child number 0
-------------------------------------
SELECT MAX (LENGTH (pe_id)) FROM pe_master_index WHERE SUBSTR (pe_id,1, 2) = 'TJ'
Plan hash value: 2553983512
-------------------------------------------------------------
| Id  | Operation             | Name               | E-Rows |
-------------------------------------------------------------
|   1 |  SORT AGGREGATE       |                    |      1 |
|*  2 |   INDEX FAST FULL SCAN| PK_PE_MASTER_INDEX |   7053 |
-------------------------------------------------------------
Outline Data
-------------
  /*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('10.2.0.3')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      INDEX_FFS(@"SEL$1" "PE_MASTER_INDEX"@"SEL$1"
              ("PE_MASTER_INDEX"."PE_ID"))
      END_OUTLINE_DATA
  */
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(SUBSTR("PE_ID",1,2)='TJ')

--建立 SUBSTR (pe_id, 1, 2),LENGTH (pe_id),这样的函数索引在这个版本下,会使用新建的索引,但是执行计划还是INDEX FAST FULL
--SCAN.优化效果不明显.好像10.2.0.4可以很好的使用这样的索引,并且执行计划走INDEX RANGE SCAN (MIN/MAX).

自己在11G下做一个测试:

create table t1 as select 'tj'||lpad(rownum,8,'0') pe_id,lpad('x',100,'x') vc from dual connect by level
create unique index scott.pk_t1 on t1(pe_id) ;
alter table t1 add constraint pk_t1  primary key (pe_id);
exec dbms_stats.gather_table_stats(USER,'T1',METHOD_OPT => 'FOR ALL COLUMNS SIZE 1 ',No_Invalidate => FALSE);
SQL> SELECT MAX (LENGTH (pe_id)) FROM t1 WHERE SUBSTR (pe_id, 1, 2) = 'tj';
MAX(LENGTH(PE_ID))
------------------
                10
SQL> @dpc '' ''
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------
SQL_ID  02mdzdry4jpt9, child number 0
-------------------------------------
SELECT MAX (LENGTH (pe_id)) FROM t1 WHERE SUBSTR (pe_id, 1, 2) = 'tj'
Plan hash value: 1953966236
-------------------------------------------------------------
| Id  | Operation             | Name  | E-Rows | Cost (%CPU)|
-------------------------------------------------------------
|   0 | SELECT STATEMENT      |       |        |    11 (100)|
|   1 |  SORT AGGREGATE       |       |      1 |            |
|*  2 |   INDEX FAST FULL SCAN| PK_T1 |    100 |    11  (10)|
-------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter(SUBSTR("PE_ID",1,2)='tj')

SQL> create  index if_t1_pe_id on t1(SUBSTR (pe_id, 1, 2),LENGTH (pe_id)) ;
SQL> SELECT MAX (LENGTH (pe_id)) FROM t1 WHERE SUBSTR (pe_id, 1, 2) = 'tj';
MAX(LENGTH(PE_ID))
------------------
                10
SQL> @dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  02mdzdry4jpt9, child number 0
-------------------------------------
SELECT MAX (LENGTH (pe_id)) FROM t1 WHERE SUBSTR (pe_id, 1, 2) = 'tj'
Plan hash value: 2812640901
--------------------------------------------------------------------------
| Id  | Operation                    | Name        | E-Rows | Cost (%CPU)|
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |        |     2 (100)|
|   1 |  SORT AGGREGATE              |             |      1 |            |
|   2 |   FIRST ROW                  |             |      1 |     2   (0)|
|*  3 |    INDEX RANGE SCAN (MIN/MAX)| IF_T1_PE_ID |      1 |     2   (0)|
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("T1"."SYS_NC00003$"='tj')

--11G下可以使用这样的索引走INDEX RANGE SCAN (MIN/MAX).

参看
http://space.itpub.net/267265/viewspace-715313
http://space.itpub.net/267265/viewspace-715314
http://space.itpub.net/267265/viewspace-715315
http://space.itpub.net/267265/viewspace-715390

时间: 2024-10-23 08:48:01

[20130319]一条sql语句的优化.txt的相关文章

[20150715]一条sql语句的优化.txt

[20150715]一条sql语句的优化.txt --生产系统发现一条语句. update presc_check t set t.diagnosis=replace(t.diagnosis,',慢性病drugs','') --第1眼看到的感觉真的很想骂人,什么能没有where条件呢? --我把这个表拷贝过来.这个表占用1G多1点,在测试环境执行看看: -- copy from system/xxxx@ip:1521/tyt create presc_check using select * f

[20131025]一条sql语句的优化.txt

[20131025]一条sql语句的优化.txt 最近在优化一条sql语句,做一个测试例子测试看看.遇到一些问题记录一下: 1.建立环境: SCOTT@test> @ver BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Productio

[20120319]一条sql语句的优化.txt

前天检查数据库,发现一天sql语句执行如下:SELECT MAX (undrug_code)   FROM undrug_info  WHERE SUBSTR (undrug_code, 1, 1) = 'F'; undrug_code是表undrug_info的主键.开始看见这个语句,感觉这样写不好,我想像的执行计划,全扫描索引,然后sort aggregate,找到最大值. 不如这样写:SELECT MAX (undrug_code)   FROM undrug_info  WHERE un

[20151209]一条sql语句的优化(续).txt

[20151209]一条sql语句的优化(续).txt http://blog.itpub.net/267265/viewspace-1852195/ --上次提到其中1条sql语句: 1.环境: SYSTEM@192.168.99.105:1521/dbcn> @ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- -------------

[20140210]一条sql语句的优化(11g).txt

  [20140210]一条sql语句的优化(11g).txt 今天下午看生产系统数据库,无意中发现一个错误,同时优化也有点小问题,写一个测试脚本. 1.建立测试环境: SCOTT@test> @ver BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 -

sql server-求助:sqlserver一条sql语句的优化 是否需要索引 建立什么样的索引合适

问题描述 求助:sqlserver一条sql语句的优化 是否需要索引 建立什么样的索引合适 1C select COUNT(*) total from (select distinct(device_token) from MDM_POLICY_UPDATE where len(device_token)=64 and SW='crmi_poly') a 解决方案 我觉得直接可以用count(device_token) 然后直接groupby device个人感觉最拖后腿的应该是len()这个函

请教大神一条sql语句的优化

问题描述 请教大神一条sql语句的优化 表名pm,以temp分组,count两个信息,一个是全部个数,另一个是status为1 id temp status 1 1 0 2 1 1 3 2 0 4 2 1 5 2 1 select total.temp ,used.c1,total.c2 from (select temp,count(1) c1 from pm group by temp ) total left join (select temp,count(1) c2 from pm wh

分享几条sql语句命令优化技巧

1.应用程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数:通过 搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担:能够分 开的操作尽量分开处理,提高每次的响应速度:在数据窗口使用SQL时,尽量把使 用的索引放在选择的首列:算法的结构尽量简单:在查询时,不要过多地使用通配 符如SELECT * FROM T1语句,要用到几列就选择几列如:SELECT COL1,COL2 FROM T1:在可能的情况下尽量限制尽量结果集行数如:SELECT TOP 300 COL1,COL

一条sql语句的优化

今天跟踪程序,无意中发现一条不良的SQL语句今天跟踪程序,无意中发现一条不良的SQL语句 分析如下: SELECT   fee_stat_name, NVL (t1.b, 0)    FROM (SELECT   fee_code, NVL (SUM (tot_cost), 0) b              FROM (SELECT "IF_BALANCELIST"."FEE_CODE",                           "IF_BA