9- 最佳實踐

1.Exists比Distinct更加有效:
The DISTINCT keyword used in a SELECT clause eliminates duplicate rows in the result set. To eliminate those duplicates, Oracle performs a sort, and that sort requires time and disk space. Therefore, avoid using DISTINCT if you can tolerate having duplicate rows returned by a query. If you can't tolerate the duplicate rows, or your application can't handle them, use EXISTS in place of DISTINCT.
 
For example, assume you are trying to find the names of customers who have orders. Your query has to be based on two tables: CUSTOMER and CUST_ORDER. Using DISTINCT, your query would be written as follows:
 
方法一:使用Distinct
    SELECT DISTINCT C.CUST_NBR, C.NAME
      FROM CUSTOMER C, CUST_ORDER O
     WHERE C.CUST_NBR = O.CUST_NBR;
 
分析:先對兩個表進行內連接,再排序,剔除重複記錄
 
 
方法二:使用Exists
    SELECT C.CUST_NBR, C.NAME
      FROM CUSTOMER C
     WHERE EXISTS (SELECT 1 FROM CUST_ORDER O WHERE C.CUST_NBR = O.CUST_NBR);
 
分析:使用相關性子查詢,每次從CUSTOMER表中取出一條記錄,將其CUST_NBR值和ORDER表中的每一條記錄的CUST_NBR值進行比較,如果有相同的記錄則直接返回CUSTOMER表中該記錄的相應字段。
 
比較:使用方法二的時候,由於使用了相關性子查詢,避免了對兩個表進行內連接,同時由於採用了Exists的存在性判斷,返回1或沒有記錄返回比起對採用內連接後進行排序和剔除重複記錄要快得多。經實驗方法二的效率比方法一快九倍以上。
 
2.Exists和In:
We've found that EXISTS often performs better than IN. Let's look at an example demonstrates this. The following query uses IN to delete the orders for customers in region 5:
 
方法一:使用In
    DELETE FROM CUST_ORDER
     WHERE CUST_NBR IN (SELECT CUST_NBR FROM CUSTOMER WHERE REGION_ID = 5);
 
分析:使用非相關性子查詢先形成臨時記錄集,再對CUST_ORDER進行全表掃描比較
 
方法二:使用Exists
    DELETE FROM CUST_ORDER WHERE EXISTS (
        SELECT CUST_NBR FROM CUSTOMER
         WHERE CUST_ORDER.CUST_NBR = CUSTOMER.CUST_NBR
           AND REGION_ID = 5);
 
分析:使用相關性子查詢,每次從CUST_ORDER表中取出一條記錄和CUSTOMER的記錄進行比較,如果存在相同記錄則刪除CUST_ORDER表中對應的記錄
 
比較:當使用Exists子句的時候,查詢的執行計劃由外部表決定,相反使用In子句的時候其執行計劃是由子查詢中的表決定,Exists查詢幾乎會比In查詢要快得多,除非那些查詢中的記錄只有很少幾條的情況下
 
3.Where和Having
With the HAVING clause, the query performs the group operation first, and then filters the groups for the condition specified. The WHERE clause version of the query filters the rows before performing the group operation. The result of filtering with the WHERE clause is that there are fewer rows to summarize, and consequently the query performs better
 
4.Union和Union All
UNION ALL combines the results of two SELECT statements. UNION combines the results of two SELECT statements, and then returns only distinct rows from the combination; duplicates are eliminated. It is, therefore, obvious that to remove the duplicates, UNION performs one extra step than UNION ALL. This extra step is a sort, which is costly in terms of performance. Therefore, whenever your application can handle duplicates or you are certain that no duplicates will result, consider using UNION ALL instead of UNION.
 
5.避免不必要的轉換過程
Before your SQL can be executed by Oracle, it needs to be parsed. The importance of parsing when it comes to tuning SQL lies in the fact that no matter how many times a given SQL statement is executed, it needs to be parsed only once. During parsing, the following steps are performed (not necessarily in the sequence shown):
 
SQL語句的轉換過程:
The syntax of the SQL statement is verified.
The data dictionary is searched to verify table and column definitions.
The data dictionary is searched to verify security privileges on relevant objects.
Parse locks are acquired on the relevant objects.
The optimal execution plan is determined.
The statement is loaded into the shared SQL area (also known as the library cache) in the shared pool of 
  the system global area (SGA). The   execution plan and parse information are saved here in case the same
  statement is executed once again.
 
However, a statement is parsed only if Oracle doesn't find an identical SQL statement already in the shared SQL area (library cache) of the SGA. Before parsing a SQL statement, Oracle searches the library cache for an identical SQL statement. If Oracle finds an exact match, there is no need to parse the statement again. However, if an identical SQL statement is not found, Oracle goes through all the aforementioned steps to parse the statement.
 
The most important keyword in the previous paragraph is "identical." To share the same SQL area, two statements need to be truly identical. Two statements that look similar, or that return the same result, need not be identical. To be truly identical, the statements must:
 
·Have the same uppercase and lowercase characters.
·Have the same whitespace and newline characters.
·Reference the same objects using the same names, which must in turn have the same owners
 
If there is a possibility that your application executes the same (or similar) SQL statements multiple times, by all means try to avoid unnecessary parsing. This will improve the overall performance of your applications. The following techniques can help you reduce SQL parsing:
Use bind variables.
Use table aliases.
 
6.使用變量綁定
When multiple users use an application, they actually execute the same set of SQL statements over and over, but with different data values. For example, one customer service representative may be executing the following statement:
 
SELECT * FROM CUSTOMER WHERE CUST_NBR = 121;
while another customer service representative will be executing:
 
SELECT * FROM CUSTOMER WHERE CUST_NBR = 328;
These two statements are similar, but not "identical"—the customer ID numbers are different, therefore Oracle has to parse twice.
 
Because the only difference between these statements is the value used for the customer number, this application could be rewritten to use bind variables. In that case, the SQL statement in question could be as follows:
 
SELECT * FROM CUSTOMER WHERE CUST_NBR = :X;
 
Oracle needs to parse this statement only once. The actual customer numbers would be supplied after parsing for each execution of the statement. Multiple, concurrently executing programs could share the same copy of this SQL statement while at the same time supplying different customer number values.
 
7.使用別名
An important thing to remember while using table aliases is that if you define aliases in the FROM clause, you must use only those aliases, and not the actual table names, in the rest of the query.
 
This is where the performance aspect of using table aliases comes into play. Since the query doesn't qualify the columns NAME and ORDER_NBR, Oracle has to search both the CUSTOMER and CUST_ORDER tables while parsing this statement to find which table each of these columns belongs to. The time required for this search may be negligible for one query, but it does add up if you have a number of such queries to parse. It's good programming practice to qualify all columns in a query with table aliases, even those that are not ambiguous, so that Oracle can avoid this extra search when parsing the statement
發佈了64 篇原創文章 · 獲贊 5 · 訪問量 40萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章