1. Trang chủ
  2. » Công Nghệ Thông Tin

Oracle SQL Plus The Definitive Guide- P32 pptx

10 242 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Oracle SQL Plus The Definitive Guide
Trường học Standard University
Chuyên ngành Computer Science
Thể loại Bài luận
Năm xuất bản 2023
Thành phố New York
Định dạng
Số trang 10
Dung lượng 102,3 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The following example starts a new timer, and gives it a name of for_testing: SQL> TIMING START for_testing You stop the timer and display its final value by issuing the TIMING STOP comm

Trang 1

SQL> SELECT view_name

2 FROM dba_views

3 WHERE view_name = DBA_TABLES;

VIEW_NAME

-

DBA_TABLES

real: 110

Notice that the timing display is rather inelegant Why a heading of real is used, instead of something more descriptive like elapsed time, I don't know

When timing is on, SQL*Plus will also report the time it takes to execute a PL/SQL block Here's an example:

SQL> BEGIN

2 DBMS_OUTPUT.PUT_LINE(How long does this take?);

3 END;

4 /

How long does this take?

PL/SQL procedure successfully completed

real: 270

To turn timing off, simply issue the SET TIMING OFF command as follows:

SQL> SET TIMING OFF

When you have timing turned on, SQL*Plus displays elapsed time only for commands executed by the database server This includes SQL statements and PL/SQL blocks Elapsed time for SQL*Plus commands, such as ACCEPT and

DEFINE, is not reported

The TIMING Command

The SQL*Plus TIMING command gives you complete control over when timing starts and stops, and over what is measured With it, you can turn on a timer at any point in your script You can display the elapsed time at any point after a timer is turned on, and you can nest timers Nesting timers gives you a way to time a set of operations, maybe an entire script, while still allowing you to time each individual operation separately

The TIMING command is really useful only in scripts You can use

it interactively, but then the elapsed time will include your think time and the time it take you to type in commands

Trang 2

The syntax for the TIMING command looks like this:

TIMI[NG] [START [ timer_name ] ¦ SHOW ¦ STOP]

where:

TIMI[NG]

Is the command, which may be abbreviated to TIMI

START [timer_name]

Starts a new timer, and optionally gives it the name you provide

SHOW

Shows the current value of the most recently started timer

STOP

Stops the most recently started timer, shows its current value, then deletes it

Think of timers as being implemented on a stack Each time you issue a TIMING START command, you push a new timer onto the stack The TIMING SHOW and TIMING STOP commands each operate on whatever timer is currently

at the top of the stack To find out how many timers you have currently running, enter the TIMING command with no arguments

Starting and stopping a timer

Use the TIMING START command to start a timer If you like, you can give the timer a name, but you don't have to Timing starts the moment the command is executed The following example starts a new timer, and gives it a name of for_testing:

SQL> TIMING START for_testing

You stop the timer and display its final value by issuing the TIMING STOP command as follows:

SQL> TIMING STOP

timing for: for_testing

real: 56460

In this case, the timer ran for a total elapsed time of 56.460 seconds

Displaying the value of a timer

You can display the value of a timer without stopping it This is useful if your script is executing several SQL queries and you want to see the cumulative elapsed time after each one For example:

SQL> TIMING START for_show

SQL> TIMING SHOW

timing for: for_show

real: 2250

Trang 3

SQL> TIMING SHOW

timing for: for_show

real: 3790

SQL> TIMING SHOW

timing for: for_show

real: 5380

SQL> TIMING SHOW

timing for: for_show

real: 6920

You can see from this example that once I got going, it took me a tad more than 1 1/2 seconds to type each TIMING SHOW command

Nesting timers

Timers can be nested, allowing you to time a group of operations, while simultaneously timing each individual

operation within the larger group The following example shows a timer being started, and while that's running, two more timers are started and stopped Finally, the first timer is also stopped

SQL> TIMING START first

SQL> TIMING START second

SQL> TIMING STOP

timing for: second

real: 2630

SQL> TIMING START third

SQL> TIMING STOP

timing for: third

real: 2360

SQL> TIMING STOP

timing for: first

real: 19160

The important thing to notice here is that the first timer kept running during this entire example The total elapsed time was a bit over 19 seconds, while each of the intermediate operations took a bit over two seconds

The following example shows how this nesting feature could be used It runs a script to delete data and reports the elapsed time for each DELETE statement, as well as the total elapsed time for the script as a whole

SET ECHO ON

TIMING START entire_script

Delete project hours data and time the operation

TIMING START delete_project_hours

DELETE FROM project_hours;

TIMING STOP

Delete project data and time the operation

TIMING START delete_projects

DELETE FROM project;

TIMING STOP

Trang 4

Delete employee data and time the operation

TIMING START

DELETE FROM employee;

TIMING STOP

COMMIT;

Show the overall elapsed time for the entire script

TIMING STOP

Here is the output from running the above script:

SQL> TIMING START entire_script

SQL>

SQL> Delete project hours data and time the operation

SQL> TIMING START delete_project_hours

SQL> DELETE FROM project_hours;

SQL> TIMING STOP

timing for: delete_project_hours

real: 1100

SQL>

SQL> Delete project data and time the operation

SQL> TIMING START delete_projects

SQL> DELETE FROM project;

SQL> TIMING STOP

timing for: delete_projects

real: 160

SQL>

SQL> Delete employee data and time the operation

SQL> TIMING START

SQL> DELETE FROM employee;

SQL> TIMING STOP

real: 220

SQL>

SQL> COMMIT;

SQL>

SQL> Show the overall elapsed time for the entire script

SQL> TIMING STOP

timing for: entire_script

real: 1750

You can see that the elapsed time was displayed for each statement and for the script as a whole

Finding out how many timers you have going

The TIMER command by itself will cause SQL*Plus to report the number of timers that are currently active The

following example shows how the count goes up each time you start a timer and back down each time you stop one: SQL> TIMING START

SQL> TIMING

1 timing element in use

Trang 5

SQL> TIMING START

SQL> TIMING

2 timing elements in use

SQL> TIMING STOP

real: 3510

SQL> TIMING

1 timing element in use

SQL> TIMING STOP

real: 9170

SQL> TIMING

no timing elements in use

Stopping all timers

You can stop and delete all timers at once with the CLEAR TIMING command As each timer is stopped, its final value

is displayed Here's an example:

SQL> TIMING START first

SQL> TIMING START second

SQL> TIMING START third

SQL> CLEAR TIMING

timing for: third

real: 2300

timing for: second

real: 7250

timing for: first

real: 10160

Using EXPLAIN PLAN

EXPLAIN PLAN is a SQL statement that causes Oracle to report the execution plan it would choose for any SELECT,

INSERT, UPDATE, or DELETE statement An execution plan refers to the approach Oracle will take to retrieve the

necessary data for a statement One example of a plan would be to use an index to find the required rows Another example of an execution plan would be to sequentially read all rows in the table If you have a poorly-performing SQL statement, you can use EXPLAIN PLAN to find out how Oracle is processing it With that information, you may be able to take some corrective action to improve performance

When you use EXPLAIN PLAN, Oracle doesn't display its execution strategy on the screen; instead, it inserts rows into

a table This table is referred to as the plan table, and you must query it properly in order to see the results Of course,

the plan table must exist, so if you've never used EXPLAIN PLAN before, you may need to create the plan table first

Trang 6

Oracle occasionally adds columns to the plan table If you have a plan table created using a previous version of Oracle, you may want to drop and recreate it, just to be sure you have the most up-to-date version

Creating the Plan Table

Oracle provides a script to create the plan table It is named UTLXPLAN.SQL, and it resides in the RDBMS/ADMIN directory for your database Under Windows 95, for example, the script to create the plan table for Oracle8 will be C:

\ORAWIN95\ RDBMS80\ADMIN\UTLXPLAN.SQL You can run it from SQL*Plus like this:

SQL> DESCRIBE plan_table

Name Null? Type

- -

STATEMENT_ID VARCHAR2(30)

TIMESTAMP DATE

REMARKS VARCHAR2(80)

OPERATION VARCHAR2(30)

OPTIONS VARCHAR2(30)

OBJECT_NODE VARCHAR2(128)

OBJECT_OWNER VARCHAR2(30)

OBJECT_NAME VARCHAR2(30)

OBJECT_INSTANCE NUMBER(38)

OBJECT_TYPE VARCHAR2(30)

OPTIMIZER VARCHAR(255)

SEARCH_COLUMNS NUMBER

ID NUMBER(38)

PARENT_ID NUMBER(38)

POSITION NUMBER(38)

COST NUMBER(38)

CARDINALITY NUMBER(38)

BYTES NUMBER(38)

OTHER_TAG VARCHAR2(255)

PARTITION_START VARCHAR2(255)

PARTITION_STOP VARCHAR2(255)

PARTITION_ID NUMBER(38)

OTHER LONG

The name of the table does not have to be plan_table, but that's the default, and it's usually easiest to leave it that way If

for some reason you don't have access to the UTLXPLAN.SQL script, you can create the table manually Just be sure

that the column names and datatypes match those shown here

Trang 7

The columns in the plan table may vary a bit depending on the exact Oracle version you have The table shown above is for Oracle 8.0.3, and includes at least three columns that are new with Oracle8 The PARTITION_START,

PARTITION_STOP, and PARTITION_ID columns were added in support of Oracle8's new partitioning features

Explaining a Query

Once you have a plan table, getting Oracle to tell you the execution plan for any given query is a fairly easy task You just need to prepend the EXPLAIN PLAN command to the front of your query The syntax for EXPLAIN PLAN looks like this:

EXPLAIN PLAN

[SET STATEMENT_ID = statement_id ]

[INTO table_name]

FOR statement;

where:

statement_id

Can be anything you like, and is stored in the STATEMENT_ID field of all plan table records related to the query you are explaining It defaults to null

table_name

Is the name of the plan table, and defaults to PLAN_TABLE You only need to supply this value if you have created your plan table with some name other than the default

statement

Is the DML statement to be explained This can be an INSERT, UPDATE, DELETE, or SELECT statement, but it must not reference any data dictionary views or dynamic performance tables

Consider the following query, which returns the total number of hours worked by each employee on each project:

SELECT employee_name, project_name, sum (hours_logged)

FROM employee, project, project_hours

WHERE employee.employee_id = project_hours.employee_id

AND project.project_id = project_hours.project_id

GROUP BY employee_name, project_name;

This query can be explained using the following two commands:

DELETE FROM plan_table WHERE statement_id = HOURS_BY_PROJECT

EXPLAIN PLAN

SET STATEMENT_ID = HOURS_BY_PROJECT

FOR

SELECT employee_name, project_name, sum (hours_logged)

FROM employee, project, project_hours

Trang 8

WHERE employee employee_id = project_hours.employee_id

AND project.project_id = project_hours.project_id

GROUP BY employee_name, project_name;

When you execute this EXPLAIN PLAN command, you won't see any output That's because Oracle stores the query plan in the plan table Retrieving and interpreting the results is your next task

You must include a DELETE statement prior to the EXPLAIN PLAN statement When you explain a statement, Oracle does not clear the plan table of any previous rows with the same statement ID If rows with the same statement ID exist from previous executions of EXPLAIN PLAN, you will get very strange results

If you're the only person using the plan table, you can save yourself some typing

by omitting the WHERE clause in the DELETE statement, thereby deleting all the records in the plan table

Interpreting the Results

Having done an EXPLAIN PLAN, you retrieve and view the results by querying the plan table The statement ID is key

to doing this The plan table can contain execution plans for any number of queries The rows for each query contain the statement ID you specified in your EXPLAIN PLAN statement, so you must use this same ID when querying the plan table in order to select the plan you are interested in seeing

The plan table query

The standard way to look at an execution plan is to display it using a hierarchical query Oracle breaks query execution down into a series of nested steps, each of which feeds data up to a parent step The ultimate parent is the query itself, the output of which is returned to the application Here is a typical query used to display the plan output:

SELECT id, parent_id,

LPAD( , 2*(level-1)) ¦¦ operation ¦¦ ¦¦ options

¦¦ ¦¦ object_name ¦¦ ¦¦

DECODE(id, 0, Cost = ¦¦ position) Query Plan

FROM plan_table

START WITH id = 0 AND statement_id = &&s_statement_id

CONNECT BY prior id = parent_id AND statement_id = &&s_statement_id;

The result of this query will be a report showing the steps in the execution plan, with each child step being indented underneath its parent

Trang 9

The SHOW_PLAN Script

You don't want to type a plan table query each time you need to see a plan, so you should consider placing it in a script file The following script provides a userfriendly way to see the execution plan for a statement It first lists the

statements currently available in the plan table Then you are prompted for the one you want to look at, and finally the plan for that statement is displayed Here is the script:

SET ECHO OFF

DESCRIPTION

This script, SHOW_PLAN.SQL, displays a list of statement IDs from

the plan table, and prompts the user to enter one The plan for

that statement is then displayed using a hierarchical query

MODIFICATION HISTORY

19-Aug-1998 by Jonathan Gennick

1 Creation

SET VERIFY OFF

SET HEADING OFF

SET FEEDBACK OFF

SET PAGESIZE 0

Display a list of statement ids for the user to choose from

PROMPT

PROMPT The plan table contains execution plans

PROMPT for the following statements:

PROMPT

SELECT DISTINCT , statement_id

FROM plan_table

ORDER BY statement_id;

Ask the user to enter the name of the statement for

which the execution plan is to be shown

PROMPT

ACCEPT s_statement_id CHAR PROMPT Enter Statement ID:

PROMPT

Show the execution plan for the statement the user selected

COLUMN id FORMAT 999

COLUMN step_description FORMAT A80

SELECT id, LPAD( , 2*(level-1)) ¦¦ operation ¦¦ ¦¦ options

¦¦ ¦¦ object_name ¦¦ ¦¦

DECODE(id, 0, Cost = ¦¦ position) step_description

Trang 10

FROM plan_table

START WITH id = 0 AND statement_id = &&s_statement_id

CONNECT BY prior id = parent_id AND statement_id = &&s_statement_id

ORDER BY id, position;

SELECT PLAN_TABLE contains no execution plan for &&s_statement_id

FROM dual

WHERE &&s_statement_id NOT IN (

SELECT DISTINCT statement_id

FROM plan_table

);

Restore settings to their defaults

SET HEADING ON

SET FEEDBACK ON

SET PAGESIZE 14

Executing the SHOW _PLAN script

You can execute the SHOW_PLAN script and display the plan for the HOURS_BY_ PROJECT query explained earlier

as follows:

SQL> @show_plan

The plan table contains execution plans

for the following statements:

HOURS_BY_PROJECT

Enter Statement ID: HOURS_BY_PROJECT

0 SELECT STATEMENT Cost = 21

1 SORT GROUP BY

2 HASH JOIN

3 TABLE ACCESS FULL EMPLOYEE

4 HASH JOIN

5 TABLE ACCESS FULL PROJECT

6 TABLE ACCESS FULL PROJECT_HOURS

SQL>

Each element of this execution plan contains three pieces of information: the operation, any options that apply, and the object of that operation Usually these three elements are enough to figure out what Oracle is doing with the query, but

if you need more information about a specific step, you can always query the plan table

In order for Oracle to compute a reasonably accurate cost, you must have up-to-date statistics on the tables involved in the query Use SQL's

ANALYZE TABLE command to gather these statistics If your statistics are old, the optimizer may come up with an execution plan that won't be efficient for the data you have now

Ngày đăng: 05/07/2014, 04:20

TỪ KHÓA LIÊN QUAN