Beruflich Dokumente
Kultur Dokumente
Unnecessary large-table full-table scans (LT-FTS) - The CBO may decide to perform a fulltable scan when an index scan will retrieve the data with far less disk I/O. While not all
large-table full-table scans are unnecessary, the LT FTS is common where Oracle's Costbased SQL optimizer makes a sub-optimal access decision. When any of these conditions
are true, the optimizer may make poor decisions about the choice between a full-table
scan and an index scan, causing huge amount of unnecessary disk I/O.
Creating a function-based index - One common technique is to match the WHERE clause
of the query with a function-based index.
Using index hints - If the CBO does not have enough statistical information about an
index, you can force the CBO (temporarily) to use the index by adding an index hint to the
query.
Once the fastest execution plan is derived, the tuning professional will enforce the execution
plan by creating schema statistics to ensure that the CBO will always use the best index
access.
Returning Data
The less data that is returned the smaller the Input/Output (I/O) cost of the query.
Therefore we should instruct a select statement to return only the columns from a table we really
need.
Only columns used for display purposes or those are used in further calculations should be returned.
Obtaining Data from Other Sources
Can any of the data be obtained without querying the database?
Before writing a select statement check that you do not already have the information you require
available in the form or module you are working in.
Obtaining the information from memory is far more efficient than querying the Database.
Outer Joins
Avoid use of outer joins in select statements if possible.
An outer join will force the optimizer to do a full table and return all the data from the table that the
outer join is on.
This will also vastly increase the amount of I/O that the server has to handle.
If you have a query that use a LEFT OUTER JOIN, check it carefully to be sure that is the type of
join you really want to use.
As you may know, a LEFT OUTER JOIN is used to create a result set that includes all of the rows
from the left table specified in the clause, not just the ones in which the joined columns match.
In addition, when a row in the left table has no matching rows in the right table, the result set row
Structure of Statements
Select statements, which return identical results set, can often be written in several different ways.
Each way can often cause the optimizer to execute the statement differently thus affecting the cost
and execution time.
The Distinct Clause
The distinct clause checks the returned result set for duplicate rows.
Carefully evaluate whether your query needs the DISTINCT clause or not. It slows down virtually
every query it is in. In addition, keep in mind that in some cases, duplicate results in a query are not
a problem. If this is the case, then don't use a DISTINCT clause.
However this query returns 4 rows. Adding the title_id column made more of the result set distinct. This
often catches many people out.
UPDATE statements that modify indexed columns and INSERT or DELETE statements that
modify indexed tables take longer than if there were no index. These SQL statements modify data in
indexes as well as data in tables. They also generate additional undo and redo.
For maximum performance when joining two or more tables, the indexes on the columns to be joined
should have the same data type.
For best join performance, the indexes on the columns being joined should be numeric data types,
not CHAR or VARCHAR. The overhead is lower and join performance is faster.
Ordering of SQL Statements
Given the above information it is clear that the order in which we execute these statements
influences how long locks will be held for.
Obviously we want to hold as few locks as possible for the shortest possible time.
Once a lock is taken out it will be held for the duration of the transaction so the key is to execute
statements that lock small amounts of data first and leave the ones that lock large amounts till the
end.
The general order in which statements should be executed in a transaction is shown below.
SELECT
INSERT
DELETE
UPDATE
Updates can lock large amounts of data, sometimes entire pages or tables, we want these locks to
be held for the shortest possible duration.
Therefore updates of large amounts of data should occur at the end of transactions. This is where
the time between the lock being taken and the transaction completing is shortest.
Deletes, like updates, can lock entire pages or tables so should be placed towards the end of a
transaction.
However they should occur before updates, as the data affected by them will be removed at the end
of the transaction, so other users are less likely to want to access it.
Inserts should be placed before deletes and updates as they only lock the row they are inserting.
This will have less of an affect on others users as they probably dont know that this data exists yet
so will not be attempting to access it.
Selects statements do not modify any data so there is no need to place them in transactions at all.
However if it is unavoidable they should be placed as close to the beginning of the transaction as
possible.
Select statements take time to execute so therefore any locks that have already been taken out will
be held while the statement executes. That is why they are better positioned as early as possible, as
fewer locks will have occurred by then.
Length of Transactions
The longer a transaction is, then the longer the locks will be held for. Therefore it is important that
transactions are kept as short as possible. Removing all select statements from inside the
transaction can help. You should also obtain all the information you need to modify, create or delete
before you start a transaction. Also keep the amount of data manipulation within the transaction to
an absolute minimum, using bulk updates/deletes/inserts is advisable.
Frequently Accessed Data
Statements that modify tables that are most frequently accessed should also be placed at the end of
transactions. Any locks held on these types of tables are more likely to be blocking other users from
accessing the data. Therefore we need to reduce the time that these locks are held by placing them
as late as possible in the transaction.
PL/SQL Performance Tuning Tips
Without PL/SQL, Oracle must process SQL statements one at a time. Each SQL statement results in
another call to Oracle and higher performance overhead. In a networked environment, the overhead
can become significant. Every time a SQL statement is issued, it must be sent over the network,
creating more traffic.
With PL/SQL, an entire block of statements can be sent to Oracle at one time. This can drastically
reduce communication between your application and Oracle.
To improve package performance is to pin frequently used packages in the shared memory pool.
When a package is pinned, it is not aged out by the least recently used (LRU) algorithm that Oracle
normally uses. The package remains in memory no matter how full the pool gets or how frequently
you access the package.
If the SQL statement affects four or more database rows, the use of bulk binds (FORALL) can
improve performance considerably.
Native dynamic SQL is easier to use and much faster than the DBMS_SQL (Dynamic PL/SQL) package.
T-SQL Performance Tuning Tips
Always include a WHERE clause in your SELECT statement to narrow the number of rows returned.
If you don't use a WHERE clause, then SQL Server will perform a table scan of your table and return
all of the rows.
In some case you may want to return all rows, and not using a WHERE clause is appropriate in this
case.
Try to avoid WHERE clauses that are non-sargable.
The term "sargable" (which is in effect a made-up word) comes from the pseudo-acronym "SARG",
which stands for "Search Arguments," which refers to a WHERE clause that compares a column to a
constant value.
Non-sargable search arguments in the WHERE clause, such as "IS NULL", "<>", "!=", "!>", "!<",
"NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'" generally prevents (but not
always) the query optimizer from using an index to perform a search.