最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Oracle Index索引無效的原因與解決方法

 更新時間:2019年03月06日 10:22:04   投稿:daisy  
這篇文章主要給大家介紹了關于Oracle Index索引無效的原因與解決方法,文中通過示例代碼以及圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

索引無效原因

最近遇到一個Oracle SQL語句的性能問題,修改功能之前的運行時間平均為0.3s,可是添加新功能后,時間達到了4~5s。雖然幾張表的數(shù)據(jù)量都比較大(都在百萬級以上),但是也都有正確創(chuàng)建索引,不知道到底慢在了哪里,下面展開調(diào)查。

經(jīng)過幾次排除,把問題范圍縮小在索引上,首先在確定索引本身沒有問題的前提下,考慮索引有沒有被使用到,那么新的問題來了,怎么知道指定索引是否被啟用。

判斷索引是否被執(zhí)行

1. 分析索引

即將索引至于監(jiān)控狀態(tài)下,對索引進行分析。如下對 ID_TT_SHOHOU_HIST_002 索引進行分析

alter index ID_TT_SHOHOU_HIST_002 monitoring usage;

2. 查看v$object_usage視圖中記錄的信息

select * from v$object_usage;

字段依次為:

•INDEX_NAME --索引名

•TABLE_NAME --表名

•MONITORING --是否被監(jiān)控

• USED --是否被啟用

•START_MONITORING --監(jiān)控開始時間

•END_MONITORING --監(jiān)控結束時間

如上圖,雖然索引已經(jīng)被引用,但是速度依舊很慢,莫非是雖然啟用了索引,但是又被其他的一些原因拖慢了速度,繼續(xù)調(diào)查。

調(diào)查途中,收集到一些Oracle 數(shù)據(jù)庫不走索引的原因分享給大家

不走索引的原因

1. 在索引列上使用函數(shù)時不會使用索引

例如常見的, TO_CHAR 、 TO_DATE 、 TO_NUMBER 、 TRUNC ...等等。

此時的解決辦法可以使用 函數(shù)索引 ,顧名思義就是把使用函數(shù)后的字段整體當成索引中的字段。

如下圖中的 TO_CHAR(SHOHOU_DATE, 'YYYYMMDD') 就是一個函數(shù)索引,因為日期字段中含有時分秒,進行日期比較的時候,必須轉(zhuǎn)化成固定的格式。

CREATE INDEX ID_TT_SHOHOU_HIST_003
ON TT_SHOHOU_HIST
(DEL_FLG,TO_CHAR(SHOHOU_DATE, 'YYYYMMDD'), SHOHOU_ID)
TABLESPACE SALESPA_INDEX

2. 索引的列進行隱式的類型轉(zhuǎn)換

SELECT * FROM TABLE WHERE INDEX_COLUM = 5

上面語句中的 INDEX_COLUM 字段類型為 VARCHAR2 ,這時就會發(fā)生隱式類型轉(zhuǎn)換,類似于

SELECT * FROM TABLE WHERE TO_NUMBER(INDEX_COLUM) = 5

3. WHERE 子句中使用不等于操作

不等于操作包括: <> , != , NOT colum >= ? , NOT colum <= ?

替代方式可以使用OR, colum <> 0 =====> colum > 0 or colum < 0;

4. 使用 IS NULL 和 IS NOT NULL

替代方式:函數(shù)索引

通過 nvl(b,c) 將為空的字段轉(zhuǎn)為不為空的c值,再在函數(shù)nvl(b,c)上建立函數(shù)索引

轉(zhuǎn)換前

SELECT * FROM A WHERE B = NULL

轉(zhuǎn)換后

SELECT * FROM A WHERE NVL(B,C) = C

5. 組合索引

組合索引:由多個列構成的索引。如

CREATE INDEX INDEX_EMP ON EMP (COL1,COL2,COL3,...)

INDEX_EMP 則為復合索引, COL1 為引導列。進行查詢時,可以使用 WHERE COL1 = ? ,也可以使用 WHERE COL1 = ? AND COL2 = ? ,這樣的限制條件都會使用索引,但是 WHERE COL2 = ? ,不會使用索引,所以限制條件中包含引導列時,該限制條件才會使用組合索引。

經(jīng)過一番調(diào)查,我使用的SQL語句檢索條件中對時間列進行 TO_CHAR(TTSH.SHOHOU_DATE, 'YYYYMMDD') 格式化日期,去除掉時分秒。再建立函數(shù)索引后仍然沒有起到優(yōu)化加速的效果,仔細觀察發(fā)現(xiàn)在使用TO_CHAR格式化時間之后,又進行TO_DATE轉(zhuǎn)為時間格式和其他子查詢的字段進行比較。然后很快想到,建立一個 TO_DATE(TO_CHAR(TTSH.SHOHOU_DATE, 'YYYYMMDD'), 'YYYYMMDD') 這樣的函數(shù)索引,結果缺失提高了不少的運行速度,從4~5s縮短到了0.5s左右。

但是這只是在PL/SQL軟件中運行SQL提高了速度,實際項目運行仍然是4~5s,使用語句查看索引的使用狀況時,發(fā)現(xiàn)并沒有使用索引,但是在PL/SQL軟件中確實調(diào)用了索引,這至今都是未解之謎,如果有大神知道原因希望能幫我解答一下這個疑問。

既然不能自動調(diào)用,只能強制讓SQL走指定索引了,強制的方法如下

在 SELECT 語句后加入 /*+INDEX(TTSH ID_TT_SHOHOU_HIST_002)*/ ,其中 TTSH 是表的別名(當表有別名的時候,必須在索引前加入表的別名)

SELECT /*+INDEX(TTSH ID_TT_SHOHOU_HIST_002)*/ 
TO_DATE(TO_CHAR(TTSH.SHOHOU_DATE, 'YYYYMMDD'), 'YYYYMMDD') AS SHOHOU_DATE 
FROM TT_SHOHOU_HIST TTSH
WHERE ...

至此,SQL的效率問題已經(jīng)解決了,但是這不是最好的解決方案。

首先,目前的索引中已經(jīng)存在包含 TO_CHAR(TTSH.SHOHOU_DATE, 'YYYYMMDD') 的函數(shù)索引,又再創(chuàng)建一個 TO_DATE(TO_CHAR(TTSH.SHOHOU_DATE, 'YYYYMMDD'), 'YYYYMMDD') ,看著就很難受

其次,強制使用索引的方法需要在SQL中指定索引名,假如數(shù)據(jù)庫中的索引名發(fā)生變更,還需去更改SQL。

最好的方法是把索引字段的TO_DATE去掉,統(tǒng)一使用TO_CHAR的索引。

AND CAL.CALENDER = TO_DATE(TO_CHAR(TTSH.SHOHOU_DATE, 'YYYYMMDD'), 'YYYYMMDD')

上面的部分語句因為 CALENDER 字段是DATE類型,所以比較時使用了TO_DATE,其實只要把 CALENDER 轉(zhuǎn)化成CHAR類型就行了,雖然看起來要改動的地方很多,其實解決了更大的問題。

總結

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • Oracle數(shù)據(jù)庫如何獲取當前自然周,當前周的起始和結束日期

    Oracle數(shù)據(jù)庫如何獲取當前自然周,當前周的起始和結束日期

    Oracle數(shù)據(jù)庫如何獲取當前自然周,當前周的起始和結束日期問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Oracle數(shù)據(jù)回滾的全過程

    Oracle數(shù)據(jù)回滾的全過程

    這篇文章主要給大家介紹了關于Oracle數(shù)據(jù)回滾的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Oracle?數(shù)據(jù)庫層級遍歷查詢功能的實現(xiàn)

    Oracle?數(shù)據(jù)庫層級遍歷查詢功能的實現(xiàn)

    這篇文章主要介紹了Oracle?數(shù)據(jù)庫層級遍歷查詢,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • Oracle 11g 安裝配置方法圖文教程

    Oracle 11g 安裝配置方法圖文教程

    這篇文章主要為大家詳細介紹了Oracle 11g 下載與安裝配置方法的圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 麒麟V10更換OpenJDK為Oracle JDK的方法

    麒麟V10更換OpenJDK為Oracle JDK的方法

    這篇文章主要介紹了麒麟V10更換OpenJDK為Oracle JDK,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Oracle11g完全卸載的詳細步驟(超管用)

    Oracle11g完全卸載的詳細步驟(超管用)

    由于需要,這會兒需要卸載掉本機上的oracle 11g數(shù)據(jù)庫(我是在Windows 7系統(tǒng)上裝的),在網(wǎng)上搜的了挺多方法的,有些說的不清楚。今天腳本之家小編給大家分享一下關于oracle11g卸載步驟,需要的朋友參考下吧
    2016-11-11
  • oracle如何修改Blob類型數(shù)據(jù),批量更新數(shù)據(jù)做字符替換

    oracle如何修改Blob類型數(shù)據(jù),批量更新數(shù)據(jù)做字符替換

    這篇文章主要介紹了oracle如何修改Blob類型數(shù)據(jù),批量更新數(shù)據(jù)做字符替換問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • oracle 觸發(fā)器 學習筆記

    oracle 觸發(fā)器 學習筆記

    觸發(fā)器 是特定事件出現(xiàn)的時候,自動執(zhí)行的代碼塊。類似于存儲過程,但是用戶不能直接調(diào)用他們。
    2009-05-05
  • Oracle觸發(fā)器和程序包的基本介紹

    Oracle觸發(fā)器和程序包的基本介紹

    這篇文章主要介紹了Oracle觸發(fā)器和程序包,主要包括觸發(fā)器的概念和創(chuàng)建方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • Oracle數(shù)據(jù)庫如何更改數(shù)據(jù)文件位置

    Oracle數(shù)據(jù)庫如何更改數(shù)據(jù)文件位置

    這篇文章主要給大家介紹了關于Oracle數(shù)據(jù)庫如何更改數(shù)據(jù)文件位置的相關資料,Oracle數(shù)據(jù)庫的數(shù)據(jù)文件的位置和信息都被記錄在控制文件中,需要的朋友可以參考下
    2023-08-08

最新評論

嘉兴市| 平山县| 濉溪县| 满城县| 崇文区| 钦州市| 建宁县| 北碚区| 海阳市| 罗江县| 汉阴县| 灵寿县| 徐汇区| 宁化县| 奉新县| 沾益县| 西乡县| 泰宁县| 句容市| 宿松县| 嘉定区| 穆棱市| 瓦房店市| 德州市| 黄陵县| 资中县| 浦县| 北流市| 桂东县| 东至县| 石柱| 景德镇市| 新宁县| 武城县| 二手房| 三原县| 四会市| 岳阳市| 交口县| 叙永县| 新巴尔虎右旗|