SQL使用復合索引實現數據庫查詢的優(yōu)化
一 問題
程序再在一次查詢時出現查詢時間過長,每次查詢要1-2分鐘業(yè)務反饋用戶操作體驗很差,sql如下:
select * FROM edi_booking edibooking0_ WHERE 1 = 1 AND edibooking0_.load_port_code IN ('CNCWN', 'CNDCB', 'AA', 'CNMWN' , 'CWHSD', 'CNSHK', 'CNYTN', 'CNSKU') AND edibooking0_.carrier_code = 'WHL' AND upper(edibooking0_.so_no) LIKE upper('025%') AND edibooking0_.load_port_code = 'CNSHK' AND edibooking0_.status <= 1 AND edibooking0_.tfc_code = 'E19957' ORDER BY edibooking0_.so_no ASC;
需要對查詢進行優(yōu)化。
二 分析
還是老樣子,先看看執(zhí)行計劃,看看走沒走索引,不查不知道一查嚇一跳,執(zhí)行計劃上居然顯示走了索引,索引是函數索引upper(so_no)
,走了索引為什么還慢呢,根據以往的經驗,走了索引不是應該很快才對嗎?奇奇怪怪,于是注意到了查詢條件中還有一個條件tfc_code
,又發(fā)現這個字段其實也有建立索引,是不是數據庫的執(zhí)行計劃有問題,沒有走tfc_code索引
呢?或者說tfc_code索引
本身有問題,于是進行重建tfc_code索引
。
alter index EDI_BOOKING_IDX_TFC_CODE rebuild online;
執(zhí)行后,哇塞,查詢速度果然上來了,2s鐘返回查詢結果。查看執(zhí)行計劃,走了tfc_code索引
,nice! 但是故事還沒有結束! 過了一天后,業(yè)務又反饋查詢慢了,查看執(zhí)行計劃,走的索引又變成了upper(so_no)
。讓人頭禿。
那還個方向思考,既然走了索引,為什么還會慢?。?! 原來走了索引并不一定就會快,這是一個大大的誤區(qū)。
upper(edibooking0_.so_no) LIKE upper('025%')
這個過濾條件走了索引,但是索引的類型是range_scan
,這種類型查詢返回的數據量會比較大,這就是這次走索引還慢的問題所在,因為走了索引之后返回了150w
條數據,而150w
條數據被后去的條件過濾,這樣導致了查詢速度慢的問題。
而引發(fā)這個問題,一個是upper(so_no)
索引返回數據量大,另外一個就是oracle的執(zhí)行計劃沒有選擇最優(yōu)的索引,如果選擇tfc_code索引
,那么查詢也會很快。
三 解決方案
指定數據庫選擇索引:
由于執(zhí)行計劃是數據庫自動生成的,我們無法改變執(zhí)行計劃,但是我們可以通過指定索引的方式,讓數據庫去執(zhí)行我們指定的索引,如:
select /*+index(edibooking0_ IDX_EDI_BOOKING_SO_TFC_CT)*/* FROM edi_booking edibooking0_
但是這種有一個弊端,要對每一個執(zhí)行的語句都要進行指定索引,修改量比較大。
建立復合索引:
CREATE INDEX IDX_EDI_BOOKING_SO_TFC_CT ON edi_booking (UPPER("SO_NO"), "TFC_CODE","CONTRACT_NO");
復合索引很容易給人一種雞肋的感覺,因為他對應的查詢條件一定是他最左邊的索引字段被查詢才能生效,但是其實他是非常有用的,比如我們現在的場景,進行復核索引過濾時就會產生非常大的性能提升,最終通過建立組合索引解決問題
到此這篇關于SQL使用復合索引實現數據庫查詢的優(yōu)化的文章就介紹到這了,更多相關SQL查詢優(yōu)化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
MySQL?原理與優(yōu)化之Limit?查詢優(yōu)化
這篇文章主要介紹了MySQL?原理與優(yōu)化之Limit?查詢優(yōu)化,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-08-08MySQL binlog_ignore_db 參數的具體使用
這篇文章主要介紹了MySQL binlog_ignore_db 參數的具體作用,幫助大家更好的理解和使用MySQL數據庫,感興趣的朋友可以了解下2020-12-12Linux下MySQL5.7.18二進制包安裝教程(無默認配置文件my_default.cnf)
這篇文章主要介紹了Linux下MySQL5.7.18二進制包安裝教程(無默認配置文件my_default.cnf) ,需要的朋友可以參考下2017-05-05MySQL 可以用localhost 連接,但不能用IP連接的問題解決方法
這篇文章主要介紹了MySQL 可以用localhost 連接,但不能用IP連接的問題解決方法的相關資料,這里提供了解決方案,需要的朋友可以參考下2016-12-12union和子查詢中order?by一起使用導致排序失效問題及解決
這篇文章主要介紹了union和子查詢中order?by一起使用導致排序失效問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12mysql community server 8.0.12安裝配置方法圖文教程
這篇文章主要為大家詳細介紹了mysql community Server 8.0.12安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-08-08