PL/SQL Challenge 每日一题:2016-9-5 DBMS_XPLAN包

[复制链接]
查看11 | 回复3 | 2008-9-15 01:28:12 | 显示全部楼层 |阅读模式
(原发表于 2011-5-11)
最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可发新贴补充或纠正),其他会员如果提供有价值的分析、讨论也可获得纪念章一枚。
每两周的优胜者可获得itpub奖励的技术图书一本。
以往旧题索引:
http://www.itpub.net/forum.php?m ... eid&typeid=1808
原始出处:
http://www.plsqlchallenge.com/
作者:
ChrisSaxon
运行环境:SQLPLUS, SERVEROUTPUT已打开
注:本题给出答案时候要求给予简要说明才能得到奖品
假设Oracle用来explain plan的表已经定义好,并且我执行下列语句所在的schema能够访问这些表。
我创建了如下的表和数据:
CREATE TABLE plch_employees
(
emp_idINTEGER
, last_name VARCHAR2 (100)
)
/
BEGIN
INSERT INTO plch_employees
VALUES (1, 'Jobs');
INSERT INTO plch_employees
VALUES (2, 'Gates');
INSERT INTO plch_employees
VALUES (3, 'Ellison');
COMMIT;
END;
/
哪些选项会显示下列SQL语句的解释计划:
SELECT *
FROM plch_employees
WHERE emp_id = 1

(A)
EXPLAIN PLAN
FOR
SELECT *
FROM plch_employees
WHERE emp_id = 1
/
SELECT *
FROM TABLE (DBMS_XPLAN.display)
/
(B)
EXPLAIN PLAN
FOR
SELECT *
FROM plch_employees
WHERE emp_id = 1
/
EXPLAIN PLAN
FOR
SELECT * FROM DUAL
/
SELECT *
FROM TABLE (DBMS_XPLAN.display)
/
(C)
EXPLAIN PLAN
SET STATEMENT_ID = 'my_query'
FOR
SELECT *
FROM plch_employees
WHERE emp_id = 1
/
EXPLAIN PLAN
FOR
SELECT * FROM DUAL
/
SELECT *
FROM TABLE (

DBMS_XPLAN.display (

'PLAN_TABLE'
, 'my_query'))
/
(D)
EXPLAIN PLAN
SET STATEMENT_ID = 'employee_query'
FOR
SELECT *
FROM plch_employees
WHERE emp_id = 1
/
SELECT *
FROM TABLE (

DBMS_XPLAN.display (

'PLAN_TABLE'
, 'employee_query'))
/
(E)
EXPLAIN PLAN
SET STATEMENT_ID = 'employee_query'
FOR
SELECT *
FROM plch_employees
WHERE emp_id = 1
/
SELECT *
FROM TABLE (

DBMS_XPLAN.display (

'PLAN_TABLE'
, NULL))
/
(F)
EXPLAIN PLAN
SET STATEMENT_ID = 'find_employee_1'
FOR
SELECT *
FROM plch_employees
WHERE emp_id = 1
/
SELECT *
FROM TABLE (

DBMS_XPLAN.display (

'EXPLAIN_PLAN_TABLE'
, 'find_employee_1'))
/
(G)
EXPLAIN PLAN
FOR
SELECT *
FROM plch_employees
WHERE emp_id = 1
/
BEGIN
DBMS_XPLAN.display ();
END;
/

回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
我选ACDE:
A:将会返回上一条执行的sql语句的计划,满足要求
B:将会返回第二条sql的计划
C:指定了STATEMENT_ID = 'my_query',会返回第一条sql的计划,满足要求
D:同上
E:相当于STATEMENT_ID取默认值,返回上一条语句计划,满足要求
F,G:语法错误

回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
A  可以,EXPLAIN PLAN 之后,接着运行 SELECT * FROM TABLE (DBMS_XPLAN.display) 可以显示上条SQL的执行计划
B 这个显示的是 SELECT * FROM DUAL 的执行计划
C SQL 标识了 STATEMENT_ID = 'my_query',显示执行计划是指定了参数值,所以OK
D 指定了参数,又是紧接的,所以OK
E 是紧接的,所以OK
F 指定的存储执行计划数据的表 EXPLAIN_PLAN_TABLE 不存在,默认是 PLAN_TABLE
G DBMS_XPLAN.display () 是管道表函数,不能那样直接执行
所以答案是: ACDE
回复

使用道具 举报

千问 | 2008-9-15 01:28:12 | 显示全部楼层
答案ACDE, 2楼得奖。
A: 这个选项没有之前语句ID, 但这没问题,因为对DBMS_XPLAN.display函数的调用并没有传递值给语句ID的参数。ORACLE会自动传回最近解释过的语句的计划。
B: 这个选项会显示“SELECT * FROM DUAL”的解释计划。既然在对DBMS_XPLAN.display函数的调用中没有指定语句ID的参数,它会返回最高的plan_id值的信息。如果你正在产生计划的查询语句不带有远程数据库链接,这个plan_id这就会和最近解释过的语句相同。而这个语句并不是查询plch_employees表。
C: 对DBMS_XPLAN.display函数的调用发生在第二个查询被解释之后,但是这个例子中,调用包含了语句ID,所以它正确第返回了第一个查询的解释计划。
D: 这个选项同时正确地指定了解释计划表的名称,以及查询的语句ID,所以执行计划恰如所需地被显示了。
E: 这个选项指定了解释计划表的名称,然后将NULL作为语句ID传递,这意味着最近解释过的语句计划会被显示。
F: 这个选项本来没问题,只是缺省的计划表名称应该为"PLAN_TABLE" 而非 "EXPLAIN_PLAN_TABLE"。当这个查询被执行,ORACLE会返回如下信息而不是执行计划:
ERROR: cannot get definition for table 'EXPLAIN_PLAN_TABLE'

ORA-44002: invalid object name
G: 可悲的是,ORACLE并没有将display函数重载为过程,所以ORACLE会报错:
"PLS-00221: 'DISPLAY' is not a procedure or is undefined"
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行