1. 程式人生 > 資料庫 >oracle索引的測試例項程式碼

oracle索引的測試例項程式碼

前言

在測試oracle索引效能時大意了,沒有仔細分析資料特點,將情況特此記錄下來。

需求: 對一張100w記錄的表的 stuname列進行查詢,測試在建立索引與不建立索引的區別. 以下是開始用的建立程式碼及執行效果.

1. 隨機資料生成程式碼分析

--為測試索引而準備的隨機資料生成程式碼,先分析一下
select rownum as id,'smith'||trunc(dbms_random.value(0,100)) as stu_name,dbms_random.string('x',20) stu_pwd,to_char(add_months(sysdate,-DBMS_RANDOM.VALUE(100,200)) + rownum / 24 / 3600,'yyyy-mm-dd hh24:mi:ss') as birthday,decode( TRUNC(DBMS_RANDOM.VALUE(1,5)),1,'湖南省',2,'湖北省',3,'江西省','北京市') as address
   from dual
   connect by level <= 100; 

--先分析以下上面的程式碼

-- 偽列: rownum

-- dual : 測試表

-- || 字串聯接

--1. 測試生成100條記錄 connect by level<=100 :

--a、利用Oracle特有的“connect by”樹形連線語法生成測試記錄,“level <= 100”表示要生成100記錄;

--b、利用rownum虛擬列生成遞增的整數資料;

--c、利用sysdate函式加一些簡單運算來生成日期資料,本例中是每條記錄的時間加1秒;

-- add_months(sysdate,200)) 用當前時間 減去 至少100個月,最多200個月,來生成生日

--d、利用dbms_random.value函式生成隨機的數值型資料,都是double型,所以都加了 trunc( )以截斷小數位,本例中是生成0到100之間的隨機整數;

--e、利用dbms_random.string函式生成隨機的字元型資料,本例中是生成長度為20的隨機字串,字串中可以包括字元或數字。

2. 生成測試表及資料

--2. 正式生成100W
drop table stu_test_100w; --如果原來有,則先刪除原來的表
 
--建立表及資料
create table stu_test_100w
as
select rownum as id,99)) as stu_name,'北京市') as address
   from dual
   connect by level <= 1000000; -- 生成 100w測試資料
-- 檢視當前使用者模式下所有的表 
select * from tab where tname='STU_TEST_100W';
--先執行一次查詢,注意查詢所用的時間,此時並沒有加入索引 
select * from stu_test_100w where stu_name='smith13'; 

執行結果:

oracle索引的測試例項程式碼

以上是沒有用到索引時的執行用時 6.781秒.

下面建立索引後,再用同一查詢來測試.

--********生成索引後,再執行一次查詢
drop index index_student_test;
 
create index index_student_test
on stu_test_100w(stu_name);  --索引是針對某個表的某個列
 
--先執行一次查詢,注意查詢的時間,此時加入了索引 
select * from stu_test_100w where stu_name='smith13';  

oracle索引的測試例項程式碼

為什麼用了索引後時間查詢能還下降了呢????

分析如下:

1. 索引生成的欄位的值分存得太密集了,檢視上面的程式碼會發現我們stu_name只生成在了 smith0-99之間,即只有100種可能性,對於100w資料則言,即每個名字都有約1w個.

2。 因為資料太密集了,所以以上查詢的花的時間主要在1w條資料的顯示上, 所以我們可以觀察到不管是否用到了索引,都要共到6-7秒來顯示結果.

3. 那為什麼用了索引還慢一些呢? 這就與索引的儲存結構有關係了.oracle預設使用的是B樹索引,當使用索引列查詢時,查詢必須先檢視索引,通過索引去定位資料,而咱們的資料分佈又比較密集,所以使用索引所導致的時間損耗要大於直接磁碟搜尋的時間.

那麼如何解決呢?

隨機生成的姓名分佈廣一些(這與真實的資料也一樣). 即將隨機生成程式碼修改為 'smith'||trunc(dbms_random.value(0,9999999)) as stu_name,

drop table stu_test_100w; --如果原來有,則先刪除原來的表
--重新生成表及隨機資料,注意 stu_name列的取值範圍加大
create table stu_test_100w
as
select rownum as id,'北京市') as address
   from dual
   connect by level <= 1000000; 
 
--先執行一次查詢,此時並沒有加入索引 
select * from stu_test_100w where stu_name='smith8821228'; 

執行結果如下:

oracle索引的測試例項程式碼

用時0.312秒.

接著建立索引後,再測試同一個查詢

--********生成索引後,再執行一次查詢
drop index index_student_test;
 
create index index_student_test
on stu_test_100w(stu_name);  --索引是針對某個表的某個列
--先執行一次查詢,此時加入了索引 
select * from stu_test_100w where stu_name='smith8821228';  

oracle索引的測試例項程式碼

使用索引後,同一個查詢只需0.015秒,在原來用時0.312的基礎下,下降了n倍.

總結

到此這篇關於oracle索引測試的文章就介紹到這了,更多相關oracle索引測試內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!