- 論壇徽章:
- 0
|
同樣的字段,換一個查詢條件,即將該字段的查詢值換為其他內(nèi)容,第一次查詢?nèi)詾榇蠹s200ms,第二次就小于2ms了。
搜索到詳細的解釋是:
現(xiàn)在有些sql: select count(*) from tableT where f<date
第一次執(zhí)行很慢(7~8分鐘),第二次執(zhí)行就很快(不到1秒),請問可能跟什么有關(guān)?
第一次執(zhí)行慢, 第二次,第三次, 第N次都會很快, 這也是Oracle的最大的特性. 以下做簡要說明:
Oracle在執(zhí)行過程中,把執(zhí)行過的語句存放在SGA中, 下次如果再運行同樣的SQL, 就不用再去解析該SQL,直接從SGA區(qū)中取出該SQL執(zhí)行就行, 但是前提是SQL沒有變化過, 如果修改過,就不會這樣了.
具體的控制機制是: 當有SQL運行時, 系統(tǒng)將分析后的SQL執(zhí)行完, 并列入LRU, 也就是排隊, 當該SQL在一定時間內(nèi)被再次執(zhí)行時, 直接從LRU中取出該SQL的計劃, 再次執(zhí)行, 減少分析時間. 如果一定時間沒有被執(zhí)行, 則該SQL在LRU中的位置逐漸會被新進來的SQL擠到后面. 當同一SQL運行時, 只要前次執(zhí)行過該SQL在LRU中還存在, 就不再分析, 如果一個SQL長時間不用, 那最終會被擠出LRU, 當此時再次執(zhí)行該SQL時,則系統(tǒng)會重新分析, 就會變慢. 這就是為什么樓主第一次運行需要很長時間, 而后面第N次運行的時間都很短的緣故.
當樓主經(jīng)過相當長時間后(比如,兩個小時或更長), 有很多其他的SQL運行過, 樓主再次運行時, 可能還會再需要很長時間的. 這就以為這, 被分析過的SQL已被擠出LRU.
另外, 需要說明的是:
當你的SQL為全表掃描時, 也就是執(zhí)行計劃中為(FULL)時, 則該SQL執(zhí)行后將被放到LRU的最后端, 因為全表掃描的SQL被認為是性能不夠優(yōu)化的SQL, 這樣該分析過的SQL的信息在系統(tǒng)中存在的時間會很短, 下次再次運行時, 系統(tǒng)會分析是否有索引, 如果有, 則使用有索引的優(yōu)化SQL信息作為分析信息, 放到LRU, 否則再次作為全表掃描放到最后.
可是是否可以設置oracle的默寫參數(shù),防止該問題發(fā)生呢?,還高手指點一二 |
|