2010-09-27 141 views
2

Postgres/PGSQL和oracle中查詢優化的基本原理是什麼?SQL查詢優化

+1

這是廣泛的,然後再考慮多個數據庫供應商 – 2010-09-27 04:55:57

+0

可能重複的[你最常見的SQL優化?](http://stackoverflow.com/questions/1332778/what-are-your-most-common- sql-optimizations) – Thilo 2010-09-27 04:57:51

回答

0

也許創造適當的指標,並適當縮進您的疑問,是建議最好的一塊,我可以給你

+0

縮進與優化有什麼關係?可讀性是,優化否。 – 2010-09-27 04:58:54

+0

關鍵是:「適當的」指數。查看所有查詢,他們目前使用的訪問路徑以及如何改進。不要隨意添加索引。 – Thilo 2010-09-27 04:59:07

8

我遵循以下optimization技術

1)如果使用SQL查詢變快SELECT語句中的實際列名稱而不是'*'。

對於實施例:寫查詢作爲

SELECT id, first_name, last_name, age, subject FROM student_details; 

代替:

SELECT * FROM student_details; 

2)HAVING子句用於選擇了所有行之後過濾行。它就像一個過濾器。不要將HAVING子句用於任何其他目的。 例如:編寫查詢作爲

SELECT subject, count(subject) 
FROM student_details 
WHERE subject != 'Science' 
AND subject != 'Maths' 
GROUP BY subject; 

相反的:

SELECT subject, count(subject) 
FROM student_details 
GROUP BY subject 
HAVING subject!= 'Vancouver' AND subject!= 'Toronto'; 

3)有時你可能在你的主查詢不止一個子查詢。儘量減少查詢中子查詢塊的數量。 例如:編寫查詢作爲

SELECT name 
FROM employee 
WHERE (salary, age) = (SELECT MAX (salary), MAX (age) 
FROM employee_details) 
AND dept = 'Electronics'; 

相反的:

SELECT name 
FROM employee 
WHERE salary = (SELECT MAX(salary) FROM employee_details) 
AND age = (SELECT MAX(age) FROM employee_details) 
AND emp_dept = 'Electronics'; 

4)使用運營商存在,且表中查詢相應的聯接。 a)通常IN具有最慢的性能。 b)當大多數過濾標準在子查詢中時,IN是有效的。 c)當大多數過濾標準在主要查詢中時,EXISTS是有效的。

對於實施例:寫查詢作爲

Select * from product p 
where EXISTS (select * from order_items o 
where o.product_id = p.product_id) 

代替:在使用加入其涉及具有一個對多關係的表

Select * from product p 
where product_id IN 
(select product_id from order_items 

5)使用exists DISTINCT代替。 例如:編寫查詢作爲

SELECT d.dept_id, d.dept 
FROM dept d 
WHERE EXISTS (SELECT 'X' FROM employee e WHERE e.dept = d.dept); 

相反的:

SELECT DISTINCT d.dept_id, d.dept 
FROM dept d,employee e 
WHERE e.dept = e.dept; 

6)儘量使用UNION ALL代替UNION的。 對於實施例:寫查詢作爲

SELECT id, first_name 
FROM student_details_class10 
UNION ALL 
SELECT id, first_name 
FROM sports_team; 

代替:

SELECT id, first_name, subject 
FROM student_details_class10 
UNION 
SELECT id, first_name 
FROM sports_team; 

7)小心而在WHERE子句使用的條件。 對於實施例:寫查詢作爲

SELECT id, first_name, age FROM student_details WHERE age > 10; 

代替:

SELECT id, first_name, age FROM student_details WHERE age != 10; 

收件作爲查詢

SELECT id, first_name, age 
FROM student_details 
WHERE first_name LIKE 'Chan%'; 

代替:

SELECT id, first_name, age 
FROM student_details 
WHERE SUBSTR(first_name,1,3) = 'Cha'; 

收件作爲查詢

SELECT id, first_name, age 
FROM student_details 
WHERE first_name LIKE NVL (:name, '%'); 

相反的:

SELECT id, first_name, age 
FROM student_details 
WHERE first_name = NVL (:name, first_name); 

編寫查詢作爲

SELECT product_id, product_name 
FROM product 
WHERE unit_price BETWEEN MAX(unit_price) and MIN(unit_price) 

相反的:

SELECT product_id, product_name 
FROM product 
WHERE unit_price >= MAX(unit_price) 
and unit_price <= MIN(unit_price) 

編寫查詢作爲

SELECT id, name, salary 
FROM employee 
WHERE dept = 'Electronics' 
AND location = 'Bangalore'; 

代替:對查詢前面,因爲它會被處理的一側

SELECT id, name, salary 
FROM employee 
WHERE dept || location= 'ElectronicsBangalore'; 

使用非列表達式。

編寫查詢作爲

SELECT id, name, salary 
FROM employee 
WHERE salary < 25000; 

相反的:

SELECT id, name, salary 
FROM employee 
WHERE salary + 10000 < 35000; 

編寫查詢作爲

SELECT id, first_name, age 
FROM student_details 
WHERE age > 10; 

相反的:

SELECT id, first_name, age 
FROM student_details 
WHERE age NOT = 10; 

8)使用DECODE來避免重複掃描相同的行或加入同一個表。 DECODE也可以用來代替GROUP BY或ORDER BY子句。 對於實施例:寫查詢作爲

SELECT id FROM employee 
WHERE name LIKE 'Ramesh%' 
and location = 'Bangalore'; 

代替:

SELECT DECODE(位置, '班加羅爾',ID,NULL)ID FROM僱員 WHERE名稱LIKE '%拉梅什';

9)要存儲較大的二進制對象,首先將它們放置在文件系統中並在數據庫中添加文件路徑。

10)要編寫能夠提供高效性能的查詢,請遵循一般的SQL標準規則。

a)使用單個情況下對所有SQL動詞

b)中開始的所有SQL動詞在新的一行

c)中分離爲單個空格

d)向右或向左對準的所有字最初的SQL動詞

+3

這是你給出的建議的混合包:有好的(如#5),很多規則不會加快查詢速度超過2%,錯誤的(因爲它們完全改變結果,就像#7的第一個例子)和愚蠢的(#8比較慢並且返回不同的結果,#9是基本的架構決定,#10對性能沒有影響)。 – Codo 2010-09-27 17:42:20

2

一個非常通用的方法中的動詞是:

  1. 的ident IFY其查詢的一部分是花費大部分時間
  2. 重寫,在以不同的方式,導致了同樣的結果
  3. 措施查詢的一部分再次
  4. 去#1再次,如果不提高查詢或你想進一步優化

如果重寫查詢沒有幫助,你應該考慮添加一個索引,以便數據庫不需要讀全表。但是測量,再次改變和測量的方法仍然是一樣的。

爲了識別查詢中代價高昂的部分,您可以在Oracle中使用「解釋計劃」或「Autotrace」。你可以在SQL Developer或TOAD等工具中找到它。他們會告訴你如何執行你的查詢(執行計劃)以及計劃的一部分是多麼昂貴。

如果您的數據庫具有相當大的規模,您主要需要在執行計劃中觀察全表掃描。他們是優化的首要目標。