ORACLE Optimization Suggestions

1. Select the most efficient table name order (only valid in the rule-based optimizer): ORACLE's parser processes the table names in the FROM clause
from right to left , and the FROM clause is written at the end The table (basic table driving table) will be processed first. In the case of multiple tables included in the FROM clause, you must select the table with the least number of records as the base table. If there are more than 3 table join queries, then you need to select the intersection table as the base table, and the intersection table refers to the table referenced by other tables.
2. The join order in the WHERE clause:
ORACLE uses the The bottom-up order parses the WHERE clause. According to this principle, the connection between tables must be written before other WHERE conditions, and those conditions that can filter out the maximum number of records must be written at the end of the WHERE clause.

3. SELECT clause Avoid using '*' in:
ORACLE will convert '*' into all column names in turn during the parsing process. This work is done by querying the data dictionary, which means that it will take more time

. 4. Reduce access Database times:
ORACLE performs a lot of work internally: parsing SQL statements, estimating index utilization, binding variables, reading data blocks, etc.;

5. Reset ARRAYSIZE parameters in SQL*Plus, SQL*Forms and Pro*C , can increase the amount of retrieved data for each database access, the recommended value is 200

6. Use the DECODE function to reduce processing time:
Use the DECODE function to avoid repeated scanning of the same records or repeated connections to the same table.

7. Simple integration, unrelated Database access:
if you have several simple database query statements, you can combine them into one query (even if there is no relationship between them)

8. Delete duplicate records:
the most efficient way to delete duplicate records (because ROWID is used) Example:
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) 
FROM EMP X WHERE X.EMP_NO = E.EMP_NO) ;
9. Use TRUNCATE instead of DELETE:
When deleting records in a table, under normal circumstances, rollback segments (rollback segments) are used to store information that can be recovered. If you do not have a COMMIT transaction, ORACLE will restore the data to the deletion The previous state (to be precise, the state before the delete command is executed) and when TRUNCATE is used, the rollback segment no longer stores any recoverable information. When the command is run, the data cannot be recovered. Therefore, there are very few When the resource is called, the execution time will be very short . The performance of the program is improved, and the demand is also reduced due to the resources released by  COMMIT: The resources released by COMMIT:  a. Information on the rollback segment used to restore data.  b. Locks acquired by program statements  c. redo log buffer 11. Replace the  HAVING clause with the Where clause:











Avoid using the HAVING clause, HAVING will only filter the result set after all records have been retrieved. This processing requires sorting, totaling, etc. If you can limit the number of records by the WHERE clause, you can reduce this overhead. . (non-oracle) among the three clauses that can add conditions to on, where, and having, on is the first to execute, where is second, and having is last, because on is to filter the records that do not meet the conditions before proceeding. Statistics, it can reduce the data to be processed by the intermediate operation. It is reasonable to say that the speed should be the fastest, and where should be faster than having, because it does sum after filtering data, and only uses on when two tables are joined. , so in a table, only where is left to compare with having. In the case of query statistics of this single table, if the conditions to be filtered do not involve the fields to be calculated, then their results are the same, but the rushmore technique can be used where, but having cannot, the latter is slower in terms of speed. If the calculated field is involved, it means that the value of this field is uncertain before it is calculated. According to the workflow written in the previous article, the action time of where is completed before the calculation, and the having is only after the calculation. works, so in this case the results of the two will be different. In multi-table join query, on works earlier than where. The system first combines multiple tables into a temporary table according to the join conditions between each table, then filters by where, and then calculates, and then filters by having. It can be seen that, in order for the filter condition to play a correct role, we must first understand when the condition should work, and then decide where to place it
.
Pay special attention to reducing queries to the table. Example:

SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)

13. Improve SQL efficiency through internal functions:
Complex SQL often sacrifices execution efficiency. It is very meaningful in practice to be able to master the above methods of using functions to solve problems.

14. Use table aliases (Alias):
when in When connecting multiple tables in the SQL statement, please use the alias of the table and prefix the alias to each Column. In this way, the parsing time can be reduced and the syntax errors caused by Column ambiguity can be reduced.

15. Use EXISTS instead IN, replace NOT IN with NOT EXISTS:
In many underlying table-based queries, it is often necessary to join another table in order to satisfy one condition. In this case, using EXISTS (or NOT EXISTS ) will usually improve the query performance. Efficiency. In a subquery, the NOT IN clause will perform an internal sort and merge. In either case, NOT IN is the least efficient (because it performs a full table traversal of the tables in the subquery) . To avoid using NOT IN, we can rewrite it as Outer Joins or NOT EXISTS.

Example:
(efficient) SELECT * FROM EMP (base table) WHERE EMPNO > 0 AND EXISTS (SELECT 'X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 'MELB')

(inefficient) SELECT * FROM EMP (base table) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = 'MELB')
Conclusion:
The return value of the EXISTS (including NOT EXISTS ) clause is a BOOL value. There is a subquery statement (SELECT ... FROM...) inside EXISTS, which I call the inner query statement of EXIST. The query statement within it returns a result set. The EXISTS clause returns a boolean value based on whether the result set of the query within it is empty or not.

A popular can be understood as: Substitute each row of the outer query table into the inner query as a test. If the result returned by the inner query takes a non-null value, the EXISTS clause returns TRUE, and this row can be used as the result row of the outer query. , otherwise it cannot be used as a result. 16. Identify 'inefficiently executed' SQL statements:
Although various graphical tools for SQL optimization emerge in an endless stream, it is always the best way to write your own SQL tools to solve problems:

SELECT EXECUTIONS , DISK_READS, BUFFER_GETS, 
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio, 
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run, 
SQL_TEXT 
FROM V$SQLAREA 
WHERE EXECUTIONS>0 
AND BUFFER_GETS > 0 
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8 
ORDER BY 4 DESC;
17. Use indexes to improve efficiency:
An index is a conceptual part of a table that is used to improve the efficiency of retrieving data. ORACLE uses a complex self-balancing B-tree structure. Generally, querying data through an index is faster than a full table scan. When ORACLE finds out, execute the query and Update The ORACLE optimizer will use an index when determining the best path for a statement. Also, using an index can improve efficiency when joining multiple tables. Another benefit of using an index is that it provides primary key uniqueness verification. For those LONG or LONG RAW data types, you can index almost any column. In general, using an index is especially effective on large tables. Of course, you will also find that when scanning small tables, using an index can also improve efficiency. Although using an index The query efficiency can be improved, but we must also pay attention to its cost. The index needs space for storage and regular maintenance. Whenever a record is added or deleted in the table or the index column is modified, the index itself will also be modified. . This means that INSERT, DELETE, UPDATE of each record will cost 4 or 5 more disk I/Os for this. Because indexes require additional storage space and processing, those unnecessary indexes will make query response time worse. slow.. Periodic reconstruction of the index is necessary.:
ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
18. Replace DISTINCT with EXISTS:
When submitting a query that contains one-to-many table information (such as the department table and employee table), avoid the Use DISTINCT in the SELECT clause. Generally, you can consider replacing it with EXIST. EXISTS makes the query faster, because the RDBMS core module will return the results as soon as the conditions of the subquery are met. Example:

(inefficient): 
SELECT DISTINCT DEPT_NO, DEPT_NAME FROM DEPT D , EMP E 
WHERE D.DEPT_NO = E.DEPT_NO 

(efficient): 
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT 'X' 
FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);

19. Use uppercase for sql statements ; because oracle always parses sql statements first and converts lowercase letters into Capitalize and then execute 20. Use the connector "+" to connect strings as little as possible in the java code! 21. Avoid using NOT on indexed columns  Usually, we want to avoid using NOT on indexed columns, NOT will have the same effect as using functions on indexed columns. When ORACLE "encounters" NOT, he will stop using the index Instead, perform a full table scan. 22. Avoid using calculations on indexed columns. In the WHERE clause, if the indexed column is part of the function. The optimizer will use full table scans instead of indexes. Example:  Inefficient:  SELECT … FROM DEPT WHERE SAL * 12 > 25000;  Efficient:  SELECT … FROM DEPT WHERE SAL > 25000/12; 23. Use >= instead of > Efficient:  SELECT * FROM EMP WHERE DEPTNO >= 4  Inefficient:  SELECT * FROM EMP WHERE DEPTNO >3  The difference between the two is that the former DBMS will directly jump to the first record with DEPT equal to 4 while the latter will first locate the record with DEPTNO=3 and scan forward to the first record with DEPT greater than 3 record of.























24. Replacing OR with UNION (applicable to index columns)
Normally, replacing OR in the WHERE clause with UNION will have better results. Using OR on index columns will cause a full table scan. Note that the above rules only Effective for multiple indexed columns. If there are columns that are not indexed, the query efficiency may be reduced because you do not select OR. In the following example, indexes are built on both LOC_ID and REGION. 

Efficient: 
SELECT LOC_ID , LOC_DESC , REGION 
FROM LOCATION 
WHERE LOC_ID = 10 
UNION 
SELECT LOC_ID , LOC_DESC , REGION 
FROM LOCATION 
WHERE REGION = "MELBOURNE" 

Inefficient: 
SELECT LOC_ID , LOC_DESC , REGION 
FROM LOCATION 
WHERE LOC_ID = 10 OR REGION = "MELBOURNE" 
If you insist on using OR, then The index column that needs to return the fewest records is written at the top.

25. Replacing OR with IN 
is a simple and easy-to-remember rule, but the actual execution effect still needs to be tested. Under ORACLE8i, the execution paths of the two seem to be the same . 

Inefficient: 
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30 

Efficient 
SELECT... FROM LOCATION WHERE LOC_IN IN (10,20,30);
26. Avoid using IS NULL and IS NOT NULL on indexed columns.
Avoid using any nullable columns in the index. ORACLE will not be able to use the index. For single-column indexes, if the column contains nulls, the record will not exist in the index. For compound indexes, if every column is null, the record will also not exist in the index. If at least one column is not null, the record will exist in the index. Example: If the unique index is established on the A and B columns of the table, and there is a record in the table with the A, B value (123, null), ORACLE will not accept the next record with the same A, B value (123, null) records (inserts). However, if all index columns are null, ORACLE will consider the entire key value to be null and null is not equal to null. So you can insert 1000 records with the same key value, of course they are all null ! Because nulls do not exist in the indexed column, a null comparison of an indexed column in the WHERE clause will cause ORACLE to deactivate the index.

Inefficient: (index invalidation) 
SELECT ... FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL; 

efficient: (The index is valid) 
SELECT ... FROM DEPARTMENT WHERE DEPT_CODE >=0;

27. Always use the first column of the index:
if the index is built on multiple columns, only the first column (leading column) is used where clause, the optimizer will choose to use the index. This is also a simple and important rule, when only the second column of the index is referenced, the optimizer uses a full table scan and ignores index

28, use UNION- ALL replaces UNION (if possible):
When a SQL statement needs to UNION two query result sets, the two result sets are merged in a UNION-ALL manner, and then sorted before outputting the final result. If UNION ALL is used instead of UNION, then sorting is not necessary. The efficiency will be improved accordingly. It should be noted that UNION ALL will repeatedly output the same records in the two result sets. Therefore, you still need to analyze the feasibility of using UNION ALL from the business requirements. UNION will sort the result set, this operation will The SORT_AREA_SIZE memory is used. The optimization of this memory is also very important. The following SQL can be used to query the

inefficient consumption of sorting: 
SELECT ACCT_NUM, BALANCE_AMT 
FROM DEBIT_TRANSACTIONS 
WHERE TRAN_DATE = '31-DEC-95' 
UNION 
SELECT ACCT_NUM, BALANCE_AMT 
FROM DEBIT_TRANSACTIONS 
WHERE TRAN_DATE = '31-DEC-95' 

Efficient: 
SELECT ACCT_NUM, BALANCE_AMT 
FROM DEBIT_TRANSACTIONS 
WHERE TRAN_DATE = '31-DEC-95' 
UNION ALL 
SELECT ACCT_NUM, BAL_AMT 
FROM DEBITANCE_TRANSACTIONS 
WHERE TRAN_DATE = '31-DEC-95 '
29. Use WHERE instead of ORDER BY:
The ORDER BY clause uses the index only under two strict conditions. 
All columns in ORDER BY must be included in the same index and maintain the order in which they are listed. All columns in 

ORDER BY The column must be defined as non-null. 
The index used in the WHERE clause and the index used in the ORDER BY clause cannot be concurrent.

For example: 
the table DEPT contains the following columns: 
DEPT_CODE PK NOT NULL 
DEPT_DESC NOT NULL 
DEPT_TYPE NULL

is inefficient: (index is not Use) 
SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE 

Efficient: (using index) 
SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0

30. Avoid changing the type of index columns.:
When comparing data of different data types, ORACLE automatically performs simple types on columns Conversion. 

Suppose EMPNO is a numeric indexed column. 
SELECT ... FROM EMP WHERE EMPNO = '123' 
Actually, after ORACLE type conversion, the statement is converted to: 
SELECT ... FROM EMP WHERE EMPNO = TO_NUMBER('123') 

Fortunately, , the type conversion does not occur on the indexed column, and the purpose of the index is not changed. 

Now, assume that EMP_TYPE is a character type indexed column. 
SELECT ... FROM EMP WHERE EMP_TYPE = 123 

This statement is converted by ORACLE to: 
SELECT ... FROM EMP WHERETO_NUMBER(EMP_TYPE)=123 

Because of the type conversion that occurs internally, this index will not be used! In order to avoid ORACLE from hiding your SQL It is best to express the type conversion explicitly. Note that when comparing characters and numbers, ORACLE will give priority to converting numeric types to character
types
The statement does not use an index. Here are some examples. 

In the following example, (1)'!=' will not use an index. Remember, an index can only tell you what exists in the table, not what does not exist in the table. (2) '||' is a character concatenation function. Like other functions, indexing is disabled. (3) '+' is a math function. Like other math functions, indexing is disabled. (4 ) The same index columns cannot be compared with each other, which will enable a full table scan.

32. a. If the amount of data retrieved exceeds 30% of the number of records in the table. There will be no significant efficiency improvement using an index. 

b. In certain cases, Using an index may be slower than a full table scan,  but this is a difference of the same order of magnitude. In general, using an index is several times or even thousands of times larger than a full table scan!
33. Avoid using resource-intensive operations:
with SQL statements with DISTINCT, UNION, MINUS, INTERSECT, ORDER BY will start the SQL engine
Perform a resource-intensive sort (SORT) function. DISTINCT requires one sort operation, while others require at least two sorts. In general, SQL statements with UNION, MINUS, INTERSECT can be rewritten in other ways. If your database The SORT_AREA_SIZE is well configured, using UNION, MINUS, INTERSECT can also be considered, after all, they are

very
readable The following two queries return the same results but the second one is significantly faster.

Inefficient: 
SELECT JOB , AVG(SAL) 
FROM EMP 
GROUP JOB 
HAVING JOB = 'PRESIDENT' 
OR JOB = 'MANAGER' 

Efficient: 
SELECT JOB , AVG(SAL) FROM EMP GROUP JOB HAVING JOB = 'PRESIDENT' OR JOB = 'MANAGER' AVG(SAL) 
FROM EMP 
WHERE JOB = 'PRESIDENT' 
OR JOB = 'MANAGER' 
GROUP JOB

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326552013&siteId=291194637