(1) Avoid full table scan when access through an index retrieves less than 40-50% of a relational table
(2) Avoid full table scan when it is possible get all needed data from an index, e.g. through fast full index scan, full index scan, or application of index organized tables
(1) Influence query optimizer with statistics on distribution of values in the columns of relational tables (DBMS_STAT)
(2) Influence query optimizer with system initialization parameters (OPTIMIZER_MODE, OPTIMIZER_INDEX_COST_ADJ)
(3) Influence query optimizer with the hints
(4) Make sure that conditions are specified correctly, for example
STATUS = 1 instead of NOT( STATUS <> 1) or STATUS IN (2, 3) instead STATUS <> 1 when the only values of STATUS are 1, 2, and 3
(5) Force full index scan when searching for NULLs, for example STATUS IS NOT NULL
(6) Do not disable index with a function or expression, for example FLOAT(STATUS) = 4.0 instead of STATUS = INT(4.0)
How to avoid full table scans ?
(7) Avoid unnecessary complex Boolean expressions, for example NOT(( STATUS <> 5) OR (PRICE <> 200)) instead use (STATUS = 5) AND (PRICE = 200)
(8) Transform condition to simple form, for example (LEVEL = ' A1' ) OR (LEVEL = ' A2' ) OR
(LEVEL = ' A3' ) OR (LEVEL = ' A4' ) OR
(LEVEL = ' A5' ) into LEVEL LIKE ' A_'
(1) Use multiblock transfer ( DB_FILE_MULTIBLOCK_READ_COUNT)
(2) Use data stripping to spread the data blocks across several partitions on several hard disk and to perform parallel full table scan later on
(3) Use sampling of table scans, for example SELECT * FROM PART
sample (10) selects 10% of the rows from PART table
(4) Select only required attributes instead of full rows, for example SELECT P_NAME FROM PART instead of SELECT * FROM
PART
(5) Force projections through temporary tables, for example CREATE
TABLE PNAME AS SELECT P_NAME FROM PART and later
on use a table PNAME instead of PART
(6) Reorganize a database, for example put frequently scanned relational tables on different persistent storage devices, use faster persistent storage devices to keep tables accessed more frequently
How to speed up full table scans ?
(7) Pin frequently accessed relational tables in data buffer cache or bypass data buffer cache when accessing a table
(8) Make I/O operations more efficient through application of specialised file organizations, for example raw partitions or Automatic Segment Management in Oracle
(9) Increase a size of data block (DB_BLOCK_SIZE)
(10) Use indexing to eliminate full table scans when selectivity of selections is high
(11) Reduce number of data blocks occupied by the relational tables being fully scanned
(12) Partition the relational tables
(13) Eliminate row "chaining" over multiple blocks
(14) Compress the relational tables
(15) Do not worry about the problem when a relational table is very small and it is not accessed frequently
RANK function can be used improve performance of top n class of queries
SELECT *
FROM ( SELECT L_ORDERKEY, L_LINENUMBER, L_EXTENDEDPRICE,
RANK() OVER (ORDER BY L_EXTENDEDPRICE DESC) RANKING
FROM LINEITEM )
WHERE RANKING <= 20;
DENSE_RANK function can be used improve performance of top n class of queries
SELECT *
FROM (SELECT L_ORDERKEY, L_LINENUMBER, L_EXTENDEDPRICE,
DENSE_RANK() OVER (ORDER BY L_EXTENDEDPRICE DESC) RANKING
FROM LINEITEM )
WHERE RANKING <= 20;
DENSE_RANK function can be used improve performance of top n class of queries
SELECT *
FROM (SELECT L_ORDERKEY, L_LINENUMBER, L_EXTENDEDPRICE,
DENSE_RANK() OVER (ORDER BY L_EXTENDEDPRICE DESC) RANKING
FROM LINEITEM )
WHERE RANKING <= 20;
It is possible to get min/max values from a data dictionary
SELECT UTL_RAW.CAST_TO_NUMBER(LOW_VALUE), UTL_RAW.CAST_TO_NUMBER(HIGH_VALUE)
FROM USER_TAB_COL_STATISTICS
WHERE TABLE_NAME = 'LINEITEM' AND
COLUMN_NAME = 'L_EXTENDEDPRICE';