SQL query optimization

1. ORACLE's parser processes the table names in the FROM clause from right to left, so the last table (basic table driving table) written in the FROM clause will be processed first. In the case of multiple tables in the FROM clause, you must choose the table with the fewest records as the base table.
For example:
table ceshi_xiao has 969 records and emp_xiao has 14 records.
select count(*) from emp_xiao, ceshi_xiao; (inefficient method)
select count(*) from ceshi_xiao, emp_xiao; (efficient method)

Note: The difference is not obvious because there are too few records in the ceshi_xiao table, but the difference can already be seen. When there are millions of records in the table, this gap can enlarge infinitely.

2. ORACLE parses the WHERE clause in bottom-up order.
According to this principle, joins 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.
For example:
SELECT …
FROM EMP E
WHERE SAL > 50000
AND JOB = 'MANAGER'
AND 25 < (SELECT COUNT(*) FROM EMP
WHERE MGR=E.EMPNO); (inefficient, execution time 156.3 seconds)
SELECT …
FROM EMP E
WHERE 25 < (SELECT COUNT(*) FROM EMP
WHERE MGR=E.EMPNO)
AND SAL > 50000
AND JOB = 'MANAGER'; (efficient, execution time 10.6 seconds)
Note: When performing multi-table associations, use the Where statement to minimize the result set of a single table, and use aggregate functions The result set is aggregated and then associated with other tables to minimize the amount of data in the result set.

3. Reduce the query on the table.
In SQL statements containing subqueries, special attention should be paid to reducing queries to the table.

4. Replace IN with EXISTS.
In many queries based on underlying tables, it is often necessary to join another table in order to satisfy one condition. In this case, using EXISTS (or NOT EXISTS) will generally improve the efficiency of the query. Use exists instead of IN because Exists only checks for the existence of a row, while in checks for the actual value.
For example:
SELECT *
FROM EMP (base table)
WHERE EMPNO > 0
AND DEPTNO IN (SELECT DEPTNO
FROM DEPT
WHERE LOC = 'MELB') (inefficient)
SELECT *
FROM EMP (base table)
WHERE EMPNO > 0
AND EXISTS (SELECT ' X'
FROM DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
AND LOC = 'MELB') (efficient)
The performance of SQL using IN is always relatively low. The reason is: for the SQL statement using IN, ORACLE always tries to convert it into a join of multiple tables. If the conversion is unsuccessful, the subquery in IN is executed first, and then the outer layer is queried. If the conversion is successful, the table records are converted into a connection of multiple tables. Therefore, no matter how, the SQL statement with IN always adds a conversion process. Therefore, try not to use the IN operator in business-intensive SQL.

5. Replace DISTINCT with EXISTS.
When submitting a query that contains one-to-many table information (such as a department table and an employee table), avoid using DISTINCT in the SELECT clause. You can generally consider replacing it with EXIST.
For example: SELECT DISTINCT DEPT_NO,DEPT_N
FROM DEPT D,EMP E
WHERE D.DEPT_NO = E.DEPT_NO (inefficient)
SELECT DEPT_NO,DEPT_NAME
FROM DEPT D
WHERE EXISTS ( SELECT 'X'
FROM EMP E
WHERE E.DEPT_NO = D.DEPT_NO ); (efficient)

6. Replace EXISTS with table joins.
In general, table joins are more efficient than EXISTS.
For example:
SELECT ENAME
FROM EMP E
WHERE EXISTS (SELECT 'X'
FROM DEPT
WHERE DEPT_NO = E.DEPT_NO
AND DEPT_CAT = 'A');
for efficiency. Rewritten as:
SELECT ENAME
FROM DEPT D, EMP E
WHERE E.DEPT_NO = D.DEPT_NO
AND DEPT_CAT = 'A' ;

7. 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. This is a very practical rule to keep in mind.
For example:
SELECT …
FROM DEPT
WHERE SAL * 12 > 25000; (inefficient)
SELECT …
FROM DEPT
WHERE SAL > 25000/12; (efficient)

8. Avoid using NOT on indexed columns.
In general, we want to avoid using NOT on an indexed column, NOT has the same effect as using a function on an indexed column. When ORACLE "encounters" NOT, he will stop using the index and perform a full table scan instead.

9. Do not use <>, !=, ~=, ^= operators.
The not-equal operator never uses an index, so processing it only results in a full table scan.
a <> 0 ==> a > 0 or a < 0

10. Use >= instead of >.
SELECT *
FROM EMP
WHERE DEPTNO >3 (inefficient)
SELECT *
FROM EMP
WHERE DEPTNO >= 4 (efficient)
The difference between the two is that the former DBMS will jump directly 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 DEPT Records greater than 3.

11. Do not use the like operator.
When encountering SQL statements that need to be filtered by LIKE, you can use instr instead, and the processing speed will be significantly improved.

12. Replace OR with (UNION) UNION ALL (for indexed columns).
In general, replacing OR in the WHERE clause with UNION will work well. Using OR on indexed columns will result in a full table scan. Note that the above rules are only valid for multiple indexed columns. If there are columns that are not indexed, the query efficiency may be reduced because you do not choose OR.
If you insist on using OR, you need to write the index column with the fewest returned records first. Note that the above rules are only valid for multiple indexed columns. If there are columns that are not indexed, the query efficiency may be reduced because you do not select OR.

13. Optimize GROUP BY.
To improve the efficiency of the GROUP BY statement, you can filter out unnecessary records before GROUP BY. The following two queries return the same results but the second is significantly faster.
For example:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP by JOB
HAVING JOB = 'PRESIDENT'
OR JOB = 'MANAGER' (inefficient)
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = 'PRESIDENT'
OR JOB = 'MANAGER'GROUP by JOB (efficient)
use where instead of having, where is used to filter rows, and having is used to filter groups, because after rows are grouped, having To filter groups, so try to use WHERE filter.

14. Avoid changing the type of index columns.
When comparing data of different data types, ORACLE automatically performs simple type conversions on columns.

15. The influence of SQL writing.
The influence of different writing styles of SQL for the same function and the same performance.
For example:
if a SQL is written by A programmer as select * from zl_yhjbqk
B programmer writes as select * from dlyx.zl_yhjbqk (prefix with table owner)
C programmer writes select * from DLYX.ZLYHJBQK (uppercase ) Table name)
Programmer D wrote select * from DLYX.ZLYHJBQK (with a space in the middle)
The results and execution time of the four SQLs after ORACLE analysis and sorting are the same, but from the principle of ORACLE shared memory SGA, you can It is concluded that ORACLE will analyze each SQL once and occupy shared memory. If the strings and formats of SQL are written exactly the same, ORACLE will only analyze it once, and the shared memory will only leave one analysis result. This can not only reduce the time for analyzing SQL, but also reduce the repeated information of shared memory, and ORACLE can also accurately count the execution frequency of SQL.

Summarize:
1). Try to avoid the null value judgment of the field in the where clause, otherwise it will cause the engine to give up the use of the index and perform a full table scan.
2). Try to avoid using the != or <> operator in the where clause, otherwise the engine will give up the use of the index and perform a full table scan.
3). Try to avoid using or to join conditions in the where clause, otherwise it will cause the engine to give up using the index and perform a full table scan.
4). In and not in should also be used with caution, otherwise it will result in a full table scan.
5). When using an index field as a condition, if the index is a composite index, the first field in the index must be used as a condition to ensure that the system uses the index, otherwise the index will not be used, and The field order should be as consistent as possible with the index order.
6). Do not use select * from t anywhere, replace "*" with a list of specific fields, and do not return any fields that are not used.

Guess you like

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