1. 程式人生 > >sql 多表查詢優化

sql 多表查詢優化

SELECT      A.name    , B.name    , C.name    , D.nameFROM checks A   INNERJOIN vendors BON    A.vendors_id = B.vendors_id  INNERJOIN bank CON    A.bank_id = C.bank_id  INNERJOIN stocks DON    A.stocks_id = D.stocks_id 

張敏 (西安翻譯學院計算機教研室)
摘要:資料庫效能問題一直是決策者及技術人員共同關注的焦點,影響資料庫效能的一個重要因素就是SQL查詢語句的低效率,而在SQL查詢語句中多表聯接查詢的使用頻率非常之高,最能體現查詢複雜性,往往是SQL優化的重點與難點。為了提高查詢速度,提高資料庫應用系統的執行效率,文章從分析關係資料庫多表查詢處理過程入手討論查詢優化技巧,指出多表查詢優化的原則。通過幾種優化策略的研究,在時間和空間上提高了系統的效能,在一定程度上提高了查詢效率。
關鍵詞:SQL 優化 聯接
引言
多表聯接操作往往要耗費大量的CPU時間和記憶體,所以多表聯接查詢在查詢優化中起到了至關重要的作用,是資料庫中最基本、最常用、最複雜的操作。在資料庫的管理資訊系統中,聯接查詢操作是所有資料庫操作中所佔據比重最大的操作。當資料庫系統積累到一定程度,若查詢時採用單條順序掃描,那麼掃描一遍所有的記錄可能就得花上幾十分鐘,甚至幾小時,這樣的系統就失去了現實的使用價值。採取什麼樣的查詢策略,使聯接查詢時間降低,就是本文需要研究的查詢優化問題。
1 優化原理
聯接查詢操作的前提是笛卡兒積,即要將多表中所有的元組拿來運算,再從中找出符合條件的,其本身就增加了運算的負擔,所以我們在做優化時儘量避免聯接查詢。如果必須要使用聯接查詢時也要儘量使用較少的聯接表,查詢優化力圖找出給定等價的表示式,但執行效率更高,一個查詢往往會有許多實現方法,關鍵是如何找出一個與之等價的且操作時間又少的表示式。優化的核心問題是儘可能減少查詢中各表的參與加工的資料量,從而達到優化時間和空間的目的。
2 聯接查詢優化的原則
2.1 儘量使用單表操作
給定三個關係模式:(以下例項均以此為例)
s(sno,sname,sec,birthday,email)
c(cno,cname,creadit,tname)
sc(sno,cno,score)
例:查詢1001學生選修的課程成績。
分析:在此查詢中涉及到sno和score兩個欄位,sno在s表中,score在sc表中,若要使用s和sc的聯接,
SQL語句為:SELECT score FROM s,sc WHERE s.sno=sc.sno and sno=‘1001’
則此查詢就是多表聯接查詢,這樣勢必要做笛卡兒積操作,所以會增加檢索的時間。
分析:在此查詢中涉及到的sno和score兩個欄位可以在sc表中全部找到,按照儘量使用單表操作原則,可以只用一個sc表。
SQL語句改為:SELECT score FROM sc WHERE sno=‘1001’這樣避免了聯接時的笛卡兒積操作,大大提高檢索速度。
2.2 避免不了的聯接操作要做到以下幾個原則:
2.2.1 聯接表時聯少不聯多 在做多表聯接查詢時,聯接的表的個數儘量少,這樣就可以減少查詢中參與加工的資料量,從而達到優化時間和空間的目的。
例:查詢選修了“資料庫應用”課程的學生的學號和成績。


分析:此查詢中涉及到sno、cname和score三個欄位,分別在s、c和sc中,若要使用s、c和sc的聯接,
SQL語句為:SELECT sno,score FROM s,c,sc WHERE s.sno=sc.sno and c.cno=sc.cno and cname=‘資料庫應用’
則此查詢是多表聯接查詢,並且聯接的三表中,兩兩都要做笛卡兒積操作,所以會增加檢索的時間。
分析:此查詢中涉及到sno、cname和score三個欄位,分別在c表和sc表中就可以全部找到,按照聯接表時聯少不聯多的原則,可以只用c和sc表。
SQL語句改為:SELECT sno,score FROM c,sc WHERE c.cno=sc.cno and cname=‘資料庫應用’
2.2.2 聯接表時在聯少不聯多的基礎上要能實現聯接 在做多表聯接查詢時,使聯接的表的個數儘量少,但是不能一味的追求表的個數,如果表的使用不能達到我們要查詢的資料,或者不能實現聯接,那也是不成功的。
例3:查詢選修了“資料庫應用”課程的學生的姓名。
分析:此查詢中涉及到sname和cname兩個欄位,分別在s表和c表中,若要使用s和c的聯接,SQL語句為:SELECT sname,cname FROM s,c WHERE  cname=‘資料庫應用’則此查詢是多表聯接查詢,但兩個表沒有公共屬性,所以實現不了聯接,這樣此操作就變成了單純的笛卡兒積操作,在此聯接中會查詢出不符合條件的記錄,失去了查詢的意義。
分析:此查詢中涉及到sname和cname兩個欄位,分別在s表和c表中,但是s表和c表沒有公共屬性,不能實現聯接,所以必須藉助sc表,所以此查詢是s表、c表和sc表三表的聯接。
SQL語句改為:SELECT sname,cname FROM s,c,sc WHERE s.sno=sc.sno and c.cno=sc.cno and cname=‘資料庫應用’
2.3 先篩選後聯接
當查詢多個數據表時,要先過濾後聯接。
例5:查詢所有成績大於70分的學生的資訊。
分析:要做s表和sc表兩表聯接,並篩選出符合條件的記錄。
SQL語句為:SELECT*FROM s,sc WHERE s.sno=sc.sno   and score>70
此查詢語句首先將兩個資料表按照學號進行聯接,然後再將符合條件的記錄篩選。由於兩個資料表進行聯接時有些記錄是以後要篩選掉的,且多個數據表聯接是笛卡爾積運算,消耗的時間會隨著記錄個數的增加很快地增長。
SQL語句改為:SELECT*FROM s,sc WHERE score>70 and s.sno=sc.sno
此聯接查詢語句克服了以上缺點,首先篩選出符合條件的記錄,減少了進行聯接的記錄個數,然後再執行聯接查詢,大大提高了查詢效率。
3 結束語
查詢優化要抓住關鍵問題,對於資料庫應用程式來說,重點在於如何提高SQL的執行效率。在資料庫的開發和維護過程中,多表聯接查詢的優化設計可以提高系統性能,對於資料量大的資料庫系統尤為重要。以上介紹的幾種優化策略使多表聯接查詢在時間和空間上提高了系統的效能,在一定程度上提高了查詢效率。