ORACLE存儲過程獲取索引信息-轉為MySQL索引創建語句


ORACLE存儲過程獲取索引信息-轉為MySQL索引創建語句

背景:因為在使用DataPipeline做數據同步(oracle到TiDB[語法與MySQL基本一致的數據庫])的時候發現oracle數據庫的索引是沒有被一起同步過來的,在查詢數據的時候會很慢,所以需要手動在TiDB中創建索引,這個就很麻煩啦.... 如果一個一個的手工創建,且oracle那邊沒有辦法直接將索引創建語句導出,表多且每張表的索引也很多,這種情況下,我們還是寫個存儲過程 獲取oracle表的索引信息,在存儲過程里直接拼湊為TiDB(MySQL)的索引創建語句。

 

關於ORACLE的索引信息:

1.查看當前表的索引信息

select * from user_indexes where table_name='tablename' ; -- 將tablename替換為你的表名就即可 ,也可以不指定表名,直接查詢出所有表的索引信息

 

2. 根據索引名稱,查詢到表的索引列信息

select * from user_ind_columns where index_name=upper('I1PBASEPAPER');  -- I1PBASEPAPER是上面那條語句查詢出來的 INDEX_NAME 值

 

3.一條sql語句查詢出索引相關信息 ,將tablename替換為需要的表名即可

select
  a.index_name
 , a.table_name
 , a.column_name
 ,b.index_type
 ,b.uniqueness
FROM all_ind_columns a, all_indexes b
WHERE a.index_name=b.index_name
AND a.table_name = upper('tablename')
ORDER BY a.table_name, a.index_name, a.column_position
;

 

4.來咯,上重點啦,存儲過程 取出oracle表中的所有索引並且拼湊為MYSQL的索引創建腳本輸出

思路很簡單,借用上面的查詢索引語句,循環取出我們要的索引信息(索引名稱,索引類型(唯一/非唯一),索引所屬的表名),然后手動拼湊sql即可

需要注意的點:

  唯一索引需要單獨判斷

  組合索引寫法有點不一樣,需要單獨拼接

先來一段簡單的,看看索引信息(第一段for里面的in (T1APL,tablename2)指定表名信息即可,多張表用逗號分割)

declare
begin
       for curidx in (select index_name,TABLE_NAME from user_indexes where table_name in('T1APL','tablename2')) loop
           dbms_output.put('索引:【表:'||curidx.TABLE_NAME||',     索引: '||curidx.index_name||',    索引列:');
           for curidxcol in (select * from user_ind_columns where index_name=upper(curidx.index_name)) loop
               dbms_output.put_line(curidxcol.column_name||'】');
           end loop;
       end loop;   
end;

執行上面的語句,我們會看到類似下面的數據輸出,這里組合索引列輸出會有點亂,下面的腳本會統一整理,這里只做索引基本信息獲取然后迭代出來的演示

 

 

5.來咯,放大招啦哈哈哈哈,實實在在的使用的腳本:(你只需要替換你的tablename即可使用啦)

declare
 idx_cnt int(10) ; -- 用於保存索引列的數量
begin
       for curidx in (select index_name,table_name,uniqueness from user_indexes where table_name in('tablename','T1APL')) loop
           select count(*) into idx_cnt from user_ind_columns where index_name=upper(curidx.index_name);
           if idx_cnt >1  -- 組合索引
           then
                if curidx.uniqueness = 'UNIQUE' then -- 判斷是否為 唯一索引如果是就在創建索引的時候添加 unique 關鍵字
                     dbms_output.put('ALTER  TABLE  or_lifepro.'||curidx.table_name||' add '||curidx.uniqueness||' index '||curidx.index_name||' (');
                else  
                     dbms_output.put('ALTER  TABLE  or_lifepro.'||curidx.table_name||' add  index '||curidx.index_name||'(');
                end if;     
                for curidxcol in (select * from user_ind_columns where index_name=upper(curidx.index_name)) loop
                     idx_cnt := idx_cnt -1; -- 當前循環每執行一次,變量次數減1
                     if idx_cnt=0 -- 當前循環為最后一次循環時 使用括號結束索引創建語句
                     then 
                         dbms_output.put_line(curidxcol.column_name||');');
                     else 
                         dbms_output.put(curidxcol.column_name||',');
                     end if; 
                end loop; 
           else   -- 單列索引
                for curidxcol in (select * from user_ind_columns where index_name=upper(curidx.index_name)) loop
                    if curidx.uniqueness = 'UNIQUE' then -- 判斷是否為 唯一索引如果是就在創建索引的時候添加 unique 關鍵字
                       dbms_output.put_line('ALTER  TABLE  or_lifepro.'||curidx.table_name||' add '||curidx.uniqueness||' index '||curidx.index_name||'('||curidxcol.column_name||');');
                    else  
                       dbms_output.put_line('ALTER  TABLE  or_lifepro.'||curidx.table_name||' add  index '||curidx.index_name||'('||curidxcol.column_name||');');
                    end if;     
                
                end loop; 
           end if;
       end loop;
        
end;

 

在PLSQL里面執行腳本(注意這個腳本中我添加了庫名前綴 or_lifepro[這是我TiDB里面的庫名],可以看自己喜好選擇修改為你的庫名或者刪除哦)

 

執行結果如下圖:我們可以看到這里的組合索引都是正常的輸出哦,且唯一索引也都加了UNIQUE關鍵字 

到這里我們的ORACLE索引轉換為MySQL就執行完了,接下來將輸出里面的內容復制到MySQL數據庫中執行一遍即可啦!!!

 

關於MySQL的索引信息

1.mysql查看表索引語句

show index from tablename; 

 

2.添加索引

ALTER table table_name ADD INDEX index_name (column1,column2,column3); -- 添加組合索引
ALTER table table_name ADD INDEX index_name (columnname); -- 添加普通索引
ALTER table table_name ADD UNIQUE INDEX index_name (columnname); -- 添加唯一索引

 

3.分析表,使得索引生效

analyze table tablename;

 

4.批量刪除mysql表索引

先將表索引信息刪除語句拼湊好,執行如下sql,更改你的tablename即可

SELECT i.TABLE_NAME, i.COLUMN_NAME, i.INDEX_NAME, 
CONCAT('ALTER TABLE ',i.TABLE_NAME,' DROP INDEX ',i.INDEX_NAME,' ;') 
FROM INFORMATION_SCHEMA.STATISTICS i where i.TABLE_NAME='tablename'
;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM