這是數據庫索引相關內容的最後一篇
複製代碼
對於單表,咱們知道了如何設計《最佳索引》;數據庫
可是現實中,每每比較複雜,有聯合查詢、嵌套查詢、子查詢等等;咱們從如下幾方面展開post
咱們來猜一猜,優化器比較難處理的謂詞可能有哪些?優化
確定要排除AND,這足夠簡單;大於/小於呢,單純來看也還行;between and呢;有範圍,應該能接受,那還有什麼?
好比Or,這明顯對優化器有點難了,爲何,由於它是不知足A,還得看B,等根據查詢結果來進行判斷需不須要看B;
還有LIKE, 若是LIKE以%開頭,那麼無疑給查詢帶來了難度;
複製代碼
因此呢,難的謂詞有什麼?spa
對,就是or、like、in這些,沒有辦法經過簡單的掃描得出結論的,不建議在這些列創建索引。
複製代碼
這些謂詞,咱們有個統一的稱呼,稱呼他們爲非布爾謂詞。那麼相反,
簡單直接的謂詞就是布爾謂詞,就是好的謂詞,能夠創建索引設計
跨表查詢總結起來就是自個表的部分,以及鏈接處.code
1.鏈接處是否在索引中很重要
2.就算每一個單表都是最佳索引,可是若是有大量隨機IO,仍然會致使查詢慢
select CNO, CNAME FROM TABLE1 WHERE CTYPE = 1;
select DNAME FROM TABLE2 WHERE DNO = CNO AND DCOM = 2;
對於TABLE1,最佳索引爲(CTYPE, CNO, CNAME);
對於TABLE2,最佳索引爲(DNO, DCOM, DNAME);
乍一看,若是這兩表聯合查詢,應該沒啥問題,經過CNO連接,CNO也在索引中;
實際呢,在TABLE1中,CTYPE=1查出來的CNO,可能不止1個,假設1w個;那麼對於沒個CNO,都會觸發TABLE2進行隨機訪問
咱們能夠粗略大概計算一下LRT
LRT = 10ms + 1w*0.01ms + 1w * 10ms
對於TABLE1,數據所有在索引中,訪問第一條索引起生了一次隨機訪問,剩餘索引爲順序訪問,因此是10ms + 1w*0.01ms
對於TABLE2,其訪問順序取決於TABLE1獲得的CNO,CTYPE=1的狀況下,CNO順序存儲的機率不大,咱們假設他們是分散存儲的,那麼每次FETCH CNO,就會致使一次隨機訪問索引,大概有1W*10ms的時長
最終,查詢速度並不理想,雖然每一個表都是最佳索引,問題在哪?在於跨表查詢致使的隨機訪問;
複製代碼
在上述狀況下,如何快速提高速度,若是在設計階段,不妨考慮將兩表合併,或者將CTYPE,也放入到TABLE2中;索引
每每你們特別排斥冗餘數據,可是從效率的角度出發,冗餘數據真的很差嗎,它的維護成本和效率成本有沒有好比如較一下呢?get
固然若是實際運行中數據查詢並不慢,並不須要糾結這些;若是可以經過寬索引或者半寬索引解決,就最好不要推翻或追加。class
1.當表結構設計出來時,就該開始索引的設計
2.用BQ或者QUBE進行索引設計檢查,若是仍是沒辦法知足需求,就要考慮合併表,減小跨表
3.根據應用須要嘗試繼續添加必要的索引
4.若是表增刪改的頻率很高(50次/秒),那須要用QUBE評估下最多允許添加多少索引
5.根據具體的數據庫調整策略
6.SQL編寫之後,繼續使用BQ、QUBE、BJQ等方式進行檢查
7.發佈後,使用EXPLAIN進行檢查
8.跟蹤報告
複製代碼
其餘相關章節
複製代碼
數據庫索引相關文章之一:《B樹,一點都不神祕》
數據庫索引相關文章之二:《B樹很簡單,插入so easy》
數據庫索引相關文章之三:《索引》
數據庫索引相關文章之四:《什麼索引算是好的索引》
數據庫索引相關文章之五:《如何發現及替換不合適的索引》
數據庫索引相關文章之六:《索引總結》效率