SQL> set arraysize 1
SQL> set line 100
SQL> column op format a40
SQL> column object_name format a20
SQL> column options format a20
SQL>
SQL> select lpad(' ',2*(level-1))||operation op,options,object_name,position
2 from plan_table
3 start with id = 0 and statement_id = '0001'
4 connect by prior id = parent_id and
5 statement_id = '0001'
6 /OP OPTIONS OBJECT_NAME POSITION
---------------------------------------- -------------------- -------------------- ----------
SELECT STATEMENT
SORT ORDER BY 1
MERGE JOIN OUTER 1
SORT JOIN 1
MERGE JOIN OUTER 1
SORT JOIN 1
NESTED LOOPS OUTER 1
NESTED LOOPS OUTER 1
TABLE ACCESS BY INDEX ROWID PRODUCT_INFO 1
INDEX RANGE SCAN IPRODUCT_INFO_VENDOR 1
IDOP OPTIONS OBJECT_NAME POSITION
---------------------------------------- -------------------- -------------------- ---------- TABLE ACCESS BY INDEX ROWID CUSTOMER 2
INDEX UNIQUE SCAN PK_CUSTOMER 1
TABLE ACCESS BY INDEX ROWID PRODUCT_CODE_LIST 2
INDEX UNIQUE SCAN PK_PRODUCT_CODE_LIST 1
SORT JOIN 2
TABLE ACCESS FULL FG_CATEGORY 1
SORT JOIN 2
TABLE ACCESS FULL FG_CATEGORY 1選取了 18 列SQL>
SQL> set line 100
SQL> column op format a40
SQL> column object_name format a20
SQL> column options format a20
SQL>
SQL> select lpad(' ',2*(level-1))||operation op,options,object_name,position
2 from plan_table
3 start with id = 0 and statement_id = '0001'
4 connect by prior id = parent_id and
5 statement_id = '0001'
6 /OP OPTIONS OBJECT_NAME POSITION
---------------------------------------- -------------------- -------------------- ----------
SELECT STATEMENT
SORT ORDER BY 1
MERGE JOIN OUTER 1
SORT JOIN 1
MERGE JOIN OUTER 1
SORT JOIN 1
NESTED LOOPS OUTER 1
NESTED LOOPS OUTER 1
TABLE ACCESS BY INDEX ROWID PRODUCT_INFO 1
INDEX RANGE SCAN IPRODUCT_INFO_VENDOR 1
IDOP OPTIONS OBJECT_NAME POSITION
---------------------------------------- -------------------- -------------------- ---------- TABLE ACCESS BY INDEX ROWID CUSTOMER 2
INDEX UNIQUE SCAN PK_CUSTOMER 1
TABLE ACCESS BY INDEX ROWID PRODUCT_CODE_LIST 2
INDEX UNIQUE SCAN PK_PRODUCT_CODE_LIST 1
SORT JOIN 2
TABLE ACCESS FULL FG_CATEGORY 1
SORT JOIN 2
TABLE ACCESS FULL FG_CATEGORY 1選取了 18 列SQL>
应该还有个cost列可以看成本
2
2 select '2010',
3 to_char(dense_rank()over(order by flag),'0000')||'00'||pro_code,
4 to_char(dense_rank()over(partition by div_name1 order by flag),'00')||pro_code,
5 pro_name,xm_name||'_'||pro_name,1,null,2,'440304',null,
6 null,div_name1
7 from (
8 select a.*,max(div_name)over(partition by rownum-level) div_name1 from(
9 select div_name,max(xm_code)over(partition by rownum-level) xm_code,
10 max(xm_name)over(partition by rownum-level) xm_name,
11 pro_code,pro_name,px,rownum-level flag
12 from aa_temp
13 start with xm_code is not null
14 connect by prior px=px-1 and xm_code is null)a
15 start with div_name is not null
16 connect by px=prior px+1 and div_name is null)
17 ;
Explained
SQL>
SQL> SELECT
2 id ||
3 DECODE(id, 0, '', LPAD(' ', 2*(level - 1))) || ' ' ||
4 operation || ' ' ||
5 options || ' ' ||
6 object_name || ' ' ||
7 object_type || ' ' ||
8 DECODE(cost, NULL, '', 'Cost = ' || position)
9 AS execution_plan
10 FROM plan_table
11 CONNECT BY PRIOR id = parent_id
12 AND statement_id = 'abc'
13 START WITH id = 0
14 AND statement_id = 'abc';
EXECUTION_PLAN
--------------------------------------------------------------------------------
0 SELECT STATEMENT Cost = 6
1 WINDOW SORT Cost = 1
2 WINDOW SORT Cost = 1
3 VIEW Cost = 1
4 WINDOW SORT Cost = 1
5 COUNT
6 CONNECT BY NO FILTERING WITH START-WITH
7 VIEW Cost = 1
8 WINDOW SORT Cost = 1
9 COUNT
10 CONNECT BY NO FILTERING WITH START-WITH
11 TABLE ACCESS FULL AA_TEMP TABLE Cost = 1
12 rows selected
SQL>
SELECT
id ||
DECODE(id, 0, '', LPAD(' ', 2*(level - 1))) || ' ' ||
operation || ' ' ||
options || ' ' ||
object_name || ' ' ||
object_type || ' ' ||
DECODE(cost, NULL, '', 'Cost = ' || position)
AS execution_plan
FROM plan_table
CONNECT BY PRIOR id = parent_id
AND statement_id = '&&v_statement_id'
START WITH id = 0
AND statement_id = '&v_statement_id';你上面的position实际上就是cost
每个人都有自己的知识积累呀. 我一般也是在Toad里点点.. 很少去写SQL来执行explain plan。我一般用下面这个语句来执行:
SQL>EXPLAIN PLAN FOR 你的sql语句;
然后
SELECT plan_table_output
FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));
查看结果就是前面SQL语句的执行计划。 SQL> EXPLAIN PLAN FOR SELECT * FROM SCOTT.EMP;已解释。SQL> SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------Plan hash value: 3956160932--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 1218 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| EMP | 14 | 1218 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Operation 选项里能看到是走全表扫描还是走索引的,
cost 能看出cost是多少,
Time 用了多少时间我觉得这样也挺清楚的.. 楼主的那种SQL,没用过..
INDEX RANGE SCAN索引范围扫描 IPRODUCT_INFO_VENDOR用到的索引名称
下面的亦同,OPTIONS 表示扫描方式
TABLE ACCESS FULL FG_CATEGORY全表扫描,没走索引
order by会在内存及临时段中对结果集进行排序
在数据量大的时候会降低执行效率
两表JOIN,我该将哪个表变成索引组织表呢?...
那就不要用IOT 了
SELECT e.card_no, e.cust_partno, sales.get_process (e.card_no) AS process,
NVL (sales.get_in_process_tax (e.card_no, 'N'), 0) AS in_production,
NVL (sales.get_stock_qty (e.ref_card_no, 'A', 'N'), 0) AS a_qty,
NVL (sales.get_stock_qty (e.ref_card_no, 'B', 'N'), 0) AS b_qty,
NVL (sales.get_stock_qty (e.ref_card_no, 'D', 'N'), 0) AS d_qty,
NVL (sales.get_max_produceno (e.card_no), '') AS max_produceno,
NVL (sales.get_card_prod_mat (e.card_no), '') AS prod_mat,
NVL (e.size_l, '') || '*' || NVL (size_w, '') AS sizex,
sales.get_card_all_color (e.card_no) AS color_no,
sales.get_prod_mat_detail (e.card_no) AS specw, g.weight,
x.category_text AS industry_category,
y.category_text AS product_category, z.c_short, e.insert_date
FROM sales.product_info e,
sales.product_code_list g,
(SELECT category_id, category_text
FROM erpuser.fg_category
WHERE category_type = '1') x,
(SELECT category_id, category_text
FROM erpuser.fg_category
WHERE category_type = '2') y,
(SELECT customerid, c_short
FROM erpuser.customer
WHERE customerid >= 'A') z
WHERE e.vendorid = '120100'
AND e.CANCEL <> 'Y'
AND e.card_no = g.card_no(+)
AND e.fg_category1 = x.category_id(+)
AND e.fg_category2 = y.category_id(+)
AND e.brand_customerid = z.customerid(+)
ORDER BY e.card_no用不到分析函數进行排序吧?...
只是结果集数据量很大的话,不知这个order by是否还有必要
FROM erpuser.fg_category
WHERE category_type = '1') x,
像这样的子查询没有必要,将条件加到where连接条件后面即可
sales.product_code_list g,
erpuser.fg_category x,
erpuser.fg_category y,
erpuser.customer z
WHERE e.vendorid = '120100'
AND e.CANCEL <> 'Y'
AND e.card_no = g.card_no(+)
AND e.fg_category1 = x.category_id(+)
AND e.fg_category2 = y.category_id(+)
AND e.brand_customerid = z.customerid(+)
and x.category_type(+) = '1'
and y.category_type(+) = '2'
and z.customerid(+) >= 'A'
可能影响效率的在
1.连接使用的表是否数据量比较大
2.还跟使用的自定义函数的性能有关如果表的数据量很大,但用条件过滤后记录数会大大降低,可以使用临时表
FROM sales.product_info e,
sales.product_code_list g,
(SELECT category_id, category_text
FROM erpuser.fg_category
WHERE category_type = '1') x,
(SELECT category_id, category_text
FROM erpuser.fg_category
WHERE category_type = '2') y,
(SELECT customerid, c_short
FROM erpuser.customer
WHERE customerid >= 'A') z
比如建立一个临时表e,来存储sales.product_info中cancel<>'Y'的记录,x,y,z同理
然后用建立的临时表来关联查询
as SELECT category_id, category_text
FROM erpuser.fg_category
WHERE category_type = '1'
2、跟自定义函数的性能有关怎么解释?..难道也跟order by能扯上关系?..
既然是要对结果进行排序,而且结果集只有1000条记录,order by暂时排除出讨论之列
自定义函数的性能可能会影响到运用该函数的sql性能,和排序无关。函数是公司提供的,必须使用,这点可以略过。
效率太低的话要看看索引是否还能优化,或者建临时表
你这个语句执行需要多长时间啊?
上面NVL (sales.get_max_produceno (e.card_no), '') 这样的nvl就不用加了吧,若为空,转换为空,这个转换是多余的。
那个nvl是多余的,但对效率影响不大
表分析指的是DBMS_STATS.GATHER_SCHEMA_STATS()
收集统计信息的目的是为了使基于CBO的执行计划更加准确
SELECT e.card_no, e.cust_partno, sales.get_process (e.card_no) process
, NVL (sales.get_in_process_tax (e.card_no, 'N'), 0) in_production
, NVL (sales.get_stock_qty (e.ref_card_no, 'A', 'N'), 0) a_qty
, NVL (sales.get_stock_qty (e.ref_card_no, 'B', 'N'), 0) b_qty
, NVL (sales.get_stock_qty (e.ref_card_no, 'D', 'N'), 0) d_qty
, NVL (sales.get_max_produceno (e.card_no), '') max_produceno
, NVL (sales.get_card_prod_mat (e.card_no), '') prod_mat
, NVL (e.size_l, '') || '*' || NVL (size_w, '') sizex
, sales.get_card_all_color (e.card_no) color_no
, sales.get_prod_mat_detail (e.card_no) specw, g.weight
, x.category_textindustry_category, y.category_textproduct_category
, z.c_short, e.insert_date
FROM sales.product_info e
, sales.product_code_list g
, erpuser.fg_category x
, erpuser.fg_category y
, customer z
WHERE e.vendorid = '120100'
AND e.CANCEL <> 'Y'
AND e.card_no = g.card_no(+)
AND e.fg_category1 = x.category_id(+)
AND e.fg_category2 = y.category_id(+)
AND e.brand_customerid = z.customerid(+)
AND x.category_type = '1'
AND y.category_type = '2'
AND z.customerid >= 'A'
ORDER BY e.card_no;
*. ORDER BY对1000多条结果集几乎不耗时,所以加不加ORDER BY应该执行时间相同。有一个可能,Oracle对原纪录集e表中的card_no排序而不是对结果集排序,(我只听说过在某个版本上),但看你的执行计划,SORT是对结果集的,应该不是这个的原因。如果你要排除这个因素,可以改成"ORDER BY 1"试一下。
*. 自定义函数的问题。通常执行自定义函数对性能有可能有比较大的影响,因为Oracle做成本分析的时候是不看函数内部的。但是你说了不带ORDER BY的时候执行时间很短。那自定义函数的印象应该很小。我看不出来会在哪里出问题,你做一个trace吧。set autotrace on
set timing on然后执行两次你的查询,先不带order by, 再加上order by
把trace的结果贴出来
无法找到阶段作业是别字。请检查PLUSTRACE角色是否可用
启动STATISTICS报表时发生错误
SQL> set timing on
无法找到阶段作业识别字。请检查PLUSTRACE角色是否可用
启动STATISTICS报表时发生错误
SQL> set timing on
http://www.itpub.net/thread-381342-1-1.html
export ORACLE_SID=mysid
sqlplus "/ as sysdba"就应该能以sys登陆如果不知道oracle系统用户口令,可以以root登陆,然后su - oracle
統計數值
----------------------------------------------------------
0 recursive calls
76 db block gets
56 consistent gets
0 physical reads
0 redo size
2092 bytes sent via SQL*Net to client
673 bytes received via SQL*Net from client
21 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
18 rows processed不加order by執行結果分析如下:
統計數值
----------------------------------------------------------
0 recursive calls
72 db block gets
54 consistent gets
0 physical reads
60 redo size
1976 bytes sent via SQL*Net to client
662 bytes received via SQL*Net from client
20 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
17 rows processed貌似差别好像不是很大...
执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 CONNECT BY
2 1 TABLE ACCESS (FULL) OF 'PLAN_TABLE'
3 1 TABLE ACCESS (BY USER ROWID) OF 'PLAN_TABLE'
4 1 TABLE ACCESS (FULL) OF 'PLAN_TABLE'
统计数值
----------------------------------------------------------
0 recursive calls
72 db block gets
53 consistent gets
0 physical reads
0 redo size
1976 bytes sent via SQL*Net to client
662 bytes received via SQL*Net from client
20 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
17 rows processed
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 CONNECT BY
2 1 TABLE ACCESS (FULL) OF 'PLAN_TABLE'
3 1 TABLE ACCESS (BY USER ROWID) OF 'PLAN_TABLE'
4 1 TABLE ACCESS (FULL) OF 'PLAN_TABLE'
統計數值
----------------------------------------------------------
0 recursive calls
76 db block gets
56 consistent gets
0 physical reads
0 redo size
2092 bytes sent via SQL*Net to client
673 bytes received via SQL*Net from client
21 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
18 rows processed
不明白你问的"Windows这个执行时间怎样换算"是什么意思,set timing on是跟踪Query在服务器端的执行时间,如果执行成本相同,那执行时间也应该相同。你的问题到底是什么?
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON4 rows selected.SQL> set timing on
SQL> select * from dept; DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON4 rows selected.Elapsed: 00:00:00.02
SQL>
不管什么操作系统
http://blog.csdn.net/inthirties/archive/2009/08/05/4405780.aspx
With the Partitioning option
JServer Release 8.1.6.0.0 - ProductionSQL> SELECT e.card_no, e.cust_partno,
2 sales.get_card_all_color (e.card_no) AS color_no,
3 sales.get_prod_mat_detail (e.card_no) AS specw, g.weight,
4 x.category_text AS industry_category,
5 y.category_text AS product_category, z.c_short, e.insert_date
6 FROM sales.product_info e,
7 sales.product_code_list g,
8 erpuser.fg_category x,
9 erpuser.fg_category y,
10 erpuser.customer z
11 WHERE e.vendorid = '120100'
12 AND e.CANCEL <> 'Y'
13 AND e.card_no = g.card_no(+)
14 AND e.fg_category1 = x.category_id(+)
15 AND e.fg_category2 = y.category_id(+)
16 AND x.category_type(+) = '1'
17 AND y.category_type(+) = '2'
18 AND z.customerid(+) >= 'A'
19 AND e.brand_customerid = z.customerid(+)
20 AND ROWNUM = 1
21 ORDER BY e.card_no
22 /
絯侥跋祇ネ犯. 叫ノ SET ㏑搭ぶ ARRAYSIZE ┪糤 MAXDATA
SQL> set arraysize 1
SQL> set pagesize 200
SQL> set linesize 100
SQL> set timing on
SQL> /CARD_NO CUST_PARTNO
------------ --------------------
COLOR_NO
---------------------------------------------------------------------------------------
SPECW
---------------------------------------------------------------------------------------
WEIGHT
----------
INDUSTRY_CATEGORY
---------------------------------------------------------------------------------------
PRODUCT_CATEGORY
---------------------------------------------------------------------------------------
C_SHORT
---------------------------------------------------------------------------------------
INSERT_DATE
------------------
1201000003S1
3
0珇&都--皊弘摸都珇
翲夹乓--猔種/牡夹乓
礚珇礟め
26-11る-07
real: 110
SQL>
那你试试set timing off
看看还有没有那个real出现
呵呵 繁体操作系统 繁体版Oracle 不好意思
翲夹乓--猔種/牡夹乓
礚珇礟め
26-11る-07
real: 110这已经不算繁体字了吧?是乱码吧
会不会real: 110就是显示的时间的乱码你用的是ORACLE8 我这里没环境
我机子上有10G和9i好像都是可以的