蘋果為何是Linux的最大競爭對手?
近期專案需要,做了一段時間的SQL Server效能最佳化,遇到了一些問題,也積累了一些經驗,現總結一下,與君共享。SQL Server效能最佳化涉及到許多方面,如良好的系統和資料庫設計,優質的SQL編寫,合適的資料表索引設計,甚至各種硬體因素:網路效能、伺服器的效能、作業系統的效能,甚至網路卡、交換機等。這篇文章主要講到如何改善SQL語句,還將有另一篇討論如何改善索引。
如何改善SQL語句的一些原則:
1. 按需索取欄位,跟“SELECT *”說拜拜
欄位的提取一定要按照“用多少提多少”的原則,避免使用“SELECT *”這樣的操作。做了這樣一個實驗,表tblA有1000萬資料:
select top 10000 c1, c2, c3, c4 from tblA order by c1 desc 用時:4673毫秒
select top 10000 c1, c2, c3 from tblA order by c1 desc用時:1376毫秒
select top 10000 c1, c2 from tblA order by c1 desc 用時:80毫秒
由此看來,我們每少提取一個欄位,資料的提取速度就會有相應的提升。但提升的速度還要看您捨棄的欄位的大小來判斷。
另外,關於“SELECT *“的問題,可以參考這篇文章:
http://www.cnblogs.com:80/goodspeed/archive/2007/07/20/index_coverage.html
2. 欄位名和表名要寫規範,注意大小寫
這一點要多注意,如果大小寫寫錯的話,雖然SQL仍然能正常執行,但資料庫系統會花一定的開銷和時間先要把您寫的規範成正確的,然後再執行SQL。寫對的話,這個時間就省了。
正常的: select top 10 dteTransaction, txtSystem_id from tblTransactionSystem
不小心的:select top 10 dtetransaction, txtsystem_id from tbltransactionsystem
3. 適當使用過渡表
把表的一個子集進行排序並建立臨時表,有時能加速查詢。它有助於避免多重排序操作,而且在其他方面還能簡化最佳化器的工作。例如:
SELECT cust.name,rcvbles.balance,……other columns
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>“98000”
ORDER BY cust.name
如果這個查詢要被執行多次而不止一次,可以把所有未付款的客戶找出來放在一個臨時檔案中,並按客戶的名字進行排序:
SELECT cust.name,rcvbles.balance,……other columns
INTO temp_cust_with_balance
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
ORDER BY cust.name
然後以下面的方式在臨時表中查詢:
SELECT * FROM temp_cust_with_balance
WHERE postcode>“98000”
臨時表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁碟I/O,所以查詢工作量可以得到大幅減少。注意:過渡臨時表建立後不會反映主表的修改。在主表中資料頻繁修改的情況下,注意不要丟失資料。
4. 別在where條件中做函式計算
這樣做的後果是將在每個行上進行運算,這將導致該列的索引失效而觸發全表掃描。如下SQL:
select * from users where YEAR(dteCreated) < 2007
可以改成select * from users where dteCreated
5. IN(NOT IN)運算子與EXISTS(NOT EXISTS)運算子
有時候會將一列和一系列值相比較。最簡單的辦法就是在where子句中使用子查詢。在where子句中可以使用兩種方式的子查詢。如下:
第一種方式使用IN運算子:
Select a.id from tblA a where a.id in (select b.id from tblB b)
第二種方式使用EXIST運算子:
Select a.id from tblA a where exists (select 1 from tblB b where b.id = a.id);
用IN寫出來的SQL的優點是比較容易寫及清晰易懂,這比較適合現代軟體開發的風格。但是用IN的SQL效能總是比較低的,而第二種格式要遠比第一種格式的效率高。從SQL執行的步驟來分析用IN的SQL與不用IN的SQL有以下區別:
SQL試圖將其轉換成多個表的連線,如果轉換不成功則先執行IN裡面的子查詢,再查詢外層的表記錄,如果轉換成功則直接採用多個表的連線方式查詢。由此可見用IN的SQL至少多了一個轉換的過程。一般的SQL都可以轉換成功,但對於含有分組統計等方面的SQL就不能轉換了。
第二種格式中,子查詢以’select 1’開始。運用EXISTS子句不管子查詢從表中抽取什麼資料它只檢視where子句。這樣最佳化器就不必遍歷整個表而僅根據索引就可完成工作(這裡假定在where語句中使用的列存在索引)。相對於IN子句來說,EXISTS使用相連子查詢,構造起來要比IN子查詢困難一些。
透過使用EXIST,資料庫系統會首先檢查主查詢,然後執行子查詢直到它找到第一個匹配項,這就節省了時間。資料庫系統在執行IN子查詢時,首先執行子查詢,並將獲得的結果列表存放在一個加了索引的臨時表中。在執行子查詢之前,系統先將主查詢掛起,待子查詢執行完畢,存放在臨時表中以後再執行主查詢。這也就是使用EXISTS比使用IN通常查詢速度快的原因。
同時應儘可能使用NOT EXISTS來代替NOT IN,儘管二者都使用了NOT(不能使用索引而降低速度),NOT EXISTS要比NOT IN查詢效率更高。
6. IS NULL 或 IS NOT NULL操作(判斷欄位是否為空)
不能用null作索引,任何包含null值的列都將不會被包含在索引中,因為B樹索引是不索引空值的。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高效能。
任何在where子句中使用is null或is not null的語句最佳化器是不允許使用索引的。
推薦方案:用其它相同功能的操作運算代替,如a is not null 改為 a>0 或a>’等。另外還設定欄位不允許為空,而用一個預設值代替空值,如一個datetime欄位,可以將預設時間設為“1900-01-01”。
7. > 及 < 運算子(大於或小於運算子)
大於或小於運算子一般情況下是不用調整的,因為它有索引就會採用索引查詢,但有的情況下可以對它進行最佳化,如一個表有100萬記錄,一個數值型欄位A,30 萬記錄的A=0,30萬記錄的A=1,39萬記錄的A=2,1萬記錄的A=3。那麼執行A>2與A>=3的效果就有很大的區別了,因為 A>2時sql會先找出為2的記錄索引再進行比較,而A>=3時sql則直接找到=3的記錄索引。可結合非聚集索引一起考慮。
8. LIKE運算子
LIKE 運算子可以應用萬用字元查詢,裡面的萬用字元組合可能達到幾乎是任意的查詢,但是如果用得不好則會產生效能上的問題,如LIKE ‘%5400%’ 這種查詢不會引用索引,而LIKE ‘X5400%’則會引用範圍索引。因為索引的擺放是依據欄位值升序或降序排列,like'%*'這種用法,不能利用有序的資料結構,利用二分法查詢資料。一個實際例子:用YW_YHJBQK表中營業編號後面的戶標識號可來查詢營業編號 YY_BH LIKE ‘%5400%’ 這個條件會產生全表掃描,如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 則會利用YY_BH的索引進行兩個範圍的查詢,效能肯定大大提高。
9. 查詢條件中的適當與不適當
查詢引數可以包含一下操作:=、、>=、<=、BETWEEN、部分like。其中,like當這樣使用時會用到索引:like '*%',但like'%*'就用不到索引。
不適當的查詢引數有:NOT 、!= 、<>、 !>、 !< 、NOT EXISTS、 NOT IN 、NOT LIKE等,還有一些不當的用法,例如:對資料進行計算,負向查詢、等號左邊使用函式、使用OR。上述語法都不用不上索引,降低程式的效率。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29212814/viewspace-1150885/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- NoSQL 和 Hadoop 是競爭對手嗎?SQLHadoop
- 關係的力量:PayPal是如何擊敗其早期競爭對手的
- 【董天一】IPFS的競爭對手們(一)
- 【董天一】IPFS的競爭對手們(二)
- VI的競爭對手Emacs 快速入門(轉)Mac
- Chrome 工程師:Firefox 是合作伙伴,不是競爭對手Chrome工程師Firefox
- 小米聯想為何滑出前五?智慧手機增速放緩競爭卻加劇
- 蘋果App Store又惹投訴:扶持自家應用打壓競爭對手蘋果APP
- 壟斷霸權?法國公司起訴蘋果打壓競爭對手的瀏覽器蘋果瀏覽器
- Google 故意破壞競爭對手的瀏覽器?Go瀏覽器
- 大資料分析競爭對手的重要性大資料
- 10個分析競爭對手網站的SEO策略網站
- 憑什麼打敗競爭對手?基於資料、基於分析的商業競爭
- Pipdig 使用客戶的網站 DDoS 競爭對手網站
- 蘋果遊戲訂閱服務即將上線,老對手谷歌也要參與競爭蘋果遊戲谷歌
- 智慧VR市場競爭:為何國產品牌屢屢失敗?VR
- Facebook:4Q20財報電話會議實錄 祖克伯稱未來蘋果將是競爭對手蘋果
- 合理分析競爭對手,有效提升關鍵詞排名
- 分享開發者調查評估競爭對手錶現的方法
- 不懼Linux競爭 微軟緣何斥巨資押注印度?(轉)Linux微軟
- 英媒:美批准鋼企起訴中國競爭對手或為報復“中國黑客”黑客
- IPIDEA助力商業洞察,獲取競爭對手情報Idea
- 外媒:Airbnb愛彼迎難敵中國本土競爭對手AI
- 分析顯示 Google Map 繼續領先競爭對手Go
- Sora 競爭對手融資數千萬美元,目前可免費“薅”Sora
- 谷歌招聘花樣百出 “創業公司競爭最大”是共識谷歌創業
- SEO優化中分析和超越競爭對手網站的方法優化網站
- 微軟MTV聯手挑戰蘋果iTunes面臨嚴厲競爭(轉)微軟蘋果
- 網路攻擊為何是經濟體最大的風險
- 衛報:中國智慧手機制造商正在追趕西方競爭對手
- “我們不把谷歌稱為競爭對手”|《財富》專訪任天堂美國總裁谷歌
- 創業者如何融資:相信自己,讓競爭對手當墊背,營收是必殺創業營收
- 谷歌旗下YouTube在去年9月推出了競爭對手Shorts谷歌
- 歐盟強迫微軟公開敏感Windows資訊給競爭對手微軟Windows
- 可組合的 ERP 系統如何幫你超越競爭對手?
- 製造業核心競爭力從何而來
- Linux 為何對病毒免疫(轉)Linux
- 應對競爭對手 下一代iPod產品會說話