T1表:RID,VID。RID:是報告ID,VID是病人流水ID,一個VID對應多個RID。
R1表:是遠程Oracle表,VID為主鍵,顯示病人流水基本資訊。
V視圖:select T.RID,T.VID,R.* from T1 left join R1 on T1.VID=R1.VID.
我們的查詢是:select * from V where RID=xxx;
這個搜索非常慢。
若執行:select * from V where VID=xxx 則非常快。
這個有沒有什么方法,可以讓Oracle,先查V視圖中左側T1,得出結果后,再關聯遠程表R1.這樣就很快了。
有沒有類似Hint的這種,表提示,可以指定。患者
uj5u.com熱心網友回復:
既然是左連接,那么參與連接的時候,肯定是T1表作為驅動表,也就是你說的“先查T1表”。確認下T1表的RID欄位上是否有索引?如果有,那么給一個慢查詢的執行計劃,嫌麻煩的話,可以先上個plsql developer F5出來的執行計劃
uj5u.com熱心網友回復:
T1表作為主表,不能加你所說的hint提示了。如果硬要加hint的話,也只有檢查T1.VID有索引才行。最后加hint提示走T1表的索引。
uj5u.com熱心網友回復:
這樣的。T1表,RID是主鍵,VID是有索引的。R1表,VID也有索引。
我查詢V ,select * from V where RID
uj5u.com熱心網友回復:
怎么加?
uj5u.com熱心網友回復:
如果RID上已經有了索引,那么確認一個事情:RID是不是varchar2型別,而條件中寫的是這樣的:where rid=123456,而不是where rid='123456'如果不是這種情況,請上執行計劃以作進一步的診斷~
uj5u.com熱心網友回復:
RID是字串,查詢也是按照where RID='xxx'。但我發現T1.VID 索引是多列。Index(PID,VID) 。這種索引可能用不到吧。
uj5u.com熱心網友回復:
你上面說的不是VID查詢沒問題嗎?有問題的是RID
uj5u.com熱心網友回復:
如果RID上已經有了索引,那么確認一個事情:RID是不是varchar2型別,而條件中寫的是這樣的:where rid=123456,而不是where rid='123456'
如果不是這種情況,請上執行計劃以作進一步的診斷~
RID是字串,查詢也是按照where RID='xxx'。但我發現T1.VID 索引是多列。Index(PID,VID) 。這種索引可能用不到吧。
你上面說的不是VID查詢沒問題嗎?有問題的是RID
如果你其實說的那個索引是(PID,RID)的話,那么考慮下是否可以調整這個索引的欄位組合順序,當然調換后,如果你有SQL只用到了PID,而且表上沒有以PID為前導欄位的索引,那么PID的查詢會出問題。或者,干脆直接為RID也創建一條索引。
uj5u.com熱心網友回復:
T1表的VID,是Index(PID,VID)沒說錯。我試試單獨建立一個VID索引吧。
uj5u.com熱心網友回復:
T1表的VID,是Index(PID,VID)沒說錯。
我試試單獨建立一個VID索引吧。
但是你的VID查詢不是沒問題嗎?還建VID的索引干嘛?
uj5u.com熱心網友回復:
查詢VID 是很快。但是查詢RID時,用到的Join,是用VID鏈接的。我想關聯鍵,若沒有索引,可能會影響Oracle的優化策略。
我猜,如果T1和R1的VID都有索引,可能查詢where rid='xxx'時會快些。
uj5u.com熱心網友回復:
查詢VID 是很快。
但是查詢RID時,用到的Join,是用VID鏈接的。我想關聯鍵,若沒有索引,可能會影響Oracle的優化策略。
我猜,如果T1和R1的VID都有索引,可能查詢where rid='xxx'時會快些。
所以我從一開始就在要求有執行計劃,否則就是一直盲人摸象猜猜猜啊。
從CBO一般的行為上來講,在這種跨庫查詢的時候,他必然會盡力讓網路上的開銷變得少點,所以,沒有太大意外的話,RID這個謂詞必然會被推入視圖內部過濾T1表,過濾完后講資料推向遠程資料庫做join,看你應用,正常來說就應該是個嵌套回圈,會走被驅動表,也就是遠程R1表連接欄位上的索引,在這個程序中,T1表上VID欄位的索引是無用的,除非你創建了覆寫索引,RID、VID都建在一條索引上。
另外,其實我一直懷疑你這里的T1和R1什么的是出于安全方面考慮,是加工過的,甚至SQL有些寫法你可能也做過修改,我怕這修改過后的SQL,對問題的判斷會有很大的誤導。
uj5u.com熱心網友回復:
還有,再多啰嗦幾句,dblink這種東西,能不用就不要用,無路從性能還是其他一些方面考慮,除非你R1表和T1表連接的時候,對資料的實時性要求很高,否則建議將R1表至少使用物化視圖刷至本地庫,再做join,雖然你現在的應用看似并不復雜,但若是還有涉及到資料統計什么之類的應用,就可能呵呵了~uj5u.com熱心網友回復:
給個執行計劃,這個靠猜也不好定位。uj5u.com熱心網友回復:
這樣還比較難說,你說的快,可能就是 查到了 T1的資料,只是前面10多條,而不是全部,而且沒讀完另個表的,試試建的臨時表,把出入查進去看看,比較兩個的速度!uj5u.com熱心網友回復:
如果RID上已經有了索引,那么確認一個事情:RID是不是varchar2型別,而條件中寫的是這樣的:where rid=123456,而不是where rid='123456'
如果不是這種情況,請上執行計劃以作進一步的診斷~
RID是字串,查詢也是按照where RID='xxx'。但我發現T1.VID 索引是多列。Index(PID,VID) 。這種索引可能用不到吧。
uj5u.com熱心網友回復:
Index(PID,VID)這種索引對PID,或者PID,VID組合條件生效,單獨VID不生效,組合索引是對前置生效的,不過比較新版本的oracle對這塊不懂有沒有做處理,如果都要當作索引建議單獨建兩個索引吧
如果RID上已經有了索引,那么確認一個事情:RID是不是varchar2型別,而條件中寫的是這樣的:where rid=123456,而不是where rid='123456'
如果不是這種情況,請上執行計劃以作進一步的診斷~
RID是字串,查詢也是按照where RID='xxx'。但我發現T1.VID 索引是多列。Index(PID,VID) 。這種索引可能用不到吧。
9i之后,Oracle就支持index skip scan了,當然即使走了這種索引掃描,也不一定能得到較好的性能,其實有這種索引掃描,如果不是對DML性能要求非常非常高,或者窮的連多條索引的存盤都增加不起,那么應該考慮新建一條索引。
uj5u.com熱心網友回復:
Index(PID,VID)這種索引對PID,或者PID,VID組合條件生效,單獨VID不生效,組合索引是對前置生效的,不過比較新版本的oracle對這塊不懂有沒有做處理,如果都要當作索引建議單獨建兩個索引吧
如果RID上已經有了索引,那么確認一個事情:RID是不是varchar2型別,而條件中寫的是這樣的:where rid=123456,而不是where rid='123456'
如果不是這種情況,請上執行計劃以作進一步的診斷~
RID是字串,查詢也是按照where RID='xxx'。但我發現T1.VID 索引是多列。Index(PID,VID) 。這種索引可能用不到吧。
話說樓主已經消失了,需要的資訊也缺失,看上去你提的這個問題也與樓主的煩惱無關。
上貼已經說到,Oracle自9i起就支持index skip scan,如果他組合索引中的前導欄位唯一值很少的話,那么性能對于他來說可能還是可以接受的,這不奇怪。但因為樓主一直未給出執行計劃,很多東西都是在猜,不一定是他遇到的真實情況。
uj5u.com熱心網友回復:
話說樓主已經消失了,需要的資訊也缺失,看上去你提的這個問題也與樓主的煩惱無關。uj5u.com熱心網友回復:
Index(PID,VID)這種索引對PID,或者PID,VID組合條件生效,單獨VID不生效,組合索引是對前置生效的,不過比較新版本的oracle對這塊不懂有沒有做處理,如果都要當作索引建議單獨建兩個索引吧
如果RID上已經有了索引,那么確認一個事情:RID是不是varchar2型別,而條件中寫的是這樣的:where rid=123456,而不是where rid='123456'
如果不是這種情況,請上執行計劃以作進一步的診斷~
RID是字串,查詢也是按照where RID='xxx'。但我發現T1.VID 索引是多列。Index(PID,VID) 。這種索引可能用不到吧。
話說樓主已經消失了,需要的資訊也缺失,看上去你提的這個問題也與樓主的煩惱無關。
上貼已經說到,Oracle自9i起就支持index skip scan,如果他組合索引中的前導欄位唯一值很少的話,那么性能對于他來說可能還是可以接受的,這不奇怪。但因為樓主一直未給出執行計劃,很多東西都是在猜,不一定是他遇到的真實情況。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/74994.html
標籤:高級技術
上一篇:自學Java,學習到資料庫,發現oracle sql delover連接不上服務器
下一篇:oracle用戶管理
