Oracle主鍵選擇對插入的影響
主鍵一般使用序列或者UUID
使用UUID主要優點是分散式環境下,主鍵不會重複;缺點是效能相對較低。
序列則相反,他在分散式環境下會重複,但是效能較高。
實驗分別測試序列,UUID,使用RAW型別的UUID,測試100W資料插入的時間。
建立實驗所需的表
測試結果如下:
不同的主鍵方案,不僅對索引維護有效能影響,同時也對索引的使用造成影響。(UUID作為主鍵索引的value佔用空間比序列大很多)。
同樣的查詢需求,都使用了主鍵索引,但是採用UUID作為主鍵,他的物理讀和一致性讀都遠遠超過了採用序列的情況。
所以如果沒有分散式環境的需求(例如層級資料上報),可以儘量採用序列作為主鍵。
單純就插入效能而言,序列>UUID RAW>UUID Varchar2
使用UUID主要優點是分散式環境下,主鍵不會重複;缺點是效能相對較低。
序列則相反,他在分散式環境下會重複,但是效能較高。
實驗分別測試序列,UUID,使用RAW型別的UUID,測試100W資料插入的時間。
建立實驗所需的表
-
drop table test_seq purge;
-
drop table test_uuid purge;
-
drop table test_uuid_raw purge;
-
-
--測試序列
-
create table test_seq(t_id number(8) primary key );
-
--測試UUID
-
create table test_uuid(t_id varchar2(32) primary key);
-
--測試UUID RAW
-
create table test_uuid_raw(t_id raw(16) primary key);
-
-
drop sequence seq;
-
-
create sequence seq
-
increment by 1
-
start with 1
- cache 300;
-
import java.sql.Connection;
-
import java.sql.DriverManager;
-
import java.sql.PreparedStatement;
-
import java.sql.SQLException;
-
import java.util.UUID;
-
-
import org.apache.commons.codec.DecoderException;
-
import org.apache.commons.codec.binary.Hex;
-
-
public class PrimaryKeyTest {
-
private static int _1W = 10000;
-
private static int COUNT = _1W * 100;
-
private static String URL = "jdbc:oracle:thin:127.0.0.1:1521:orcl";
-
private static String USERNAME = "edmond";
-
private static String PWD = "edmond";
-
-
private static void insertSeq() throws SQLException {
-
System.out.println("測試序列:");
-
long start = System.currentTimeMillis();
-
long end;
-
Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
-
con.setAutoCommit(false);
-
PreparedStatement ps = con.prepareStatement("insert into test_seq(t_id) values(seq.nextval)");
-
for (int i = 0; i < COUNT; i++) {
-
if (i == _1W) {
-
end = System.currentTimeMillis();
-
System.out.println("1W:" + (end - start));
-
} else if (i == _1W * 10) {
-
end = System.currentTimeMillis();
-
System.out.println("10W:" + (end - start));
-
} else if (i == _1W * 20) {
-
end = System.currentTimeMillis();
-
System.out.println("20W:" + (end - start));
-
} else if (i == _1W * 50) {
-
end = System.currentTimeMillis();
-
System.out.println("50W:" + (end - start));
-
} else if (i == _1W * 80) {
-
end = System.currentTimeMillis();
-
System.out.println("80W:" + (end - start));
-
}
-
-
ps.addBatch();
-
if (i % (10 * _1W) == 0) {
-
ps.executeBatch();
-
}
-
}
-
ps.executeBatch();
-
con.commit();
-
ps.close();
-
con.close();
-
-
end = System.currentTimeMillis();
-
System.out.println("100W:" + (end - start));
-
-
}
-
-
private static void insertUUID() throws SQLException {
-
System.out.println("測試UUID:");
-
long start = System.currentTimeMillis();
-
long end;
-
Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
-
con.setAutoCommit(false);
-
PreparedStatement ps = con.prepareStatement("insert into test_uuid(t_id) values(?)");
-
for (int i = 0; i < COUNT; i++) {
-
if (i == _1W) {
-
end = System.currentTimeMillis();
-
System.out.println("1W:" + (end - start));
-
} else if (i == _1W * 10) {
-
end = System.currentTimeMillis();
-
System.out.println("10W:" + (end - start));
-
} else if (i == _1W * 20) {
-
end = System.currentTimeMillis();
-
System.out.println("20W:" + (end - start));
-
} else if (i == _1W * 50) {
-
end = System.currentTimeMillis();
-
System.out.println("50W:" + (end - start));
-
} else if (i == _1W * 80) {
-
end = System.currentTimeMillis();
-
System.out.println("80W:" + (end - start));
-
}
-
-
String id = UUID.randomUUID().toString().replaceAll("-", "");
-
ps.setString(1, id);
-
ps.addBatch();
-
-
if (i % (10 * _1W) == 0) {
-
ps.executeBatch();
-
}
-
}
-
ps.executeBatch();
-
con.commit();
-
ps.close();
-
con.close();
-
-
end = System.currentTimeMillis();
-
System.out.println("100W:" + (end - start));
-
-
}
-
-
private static void insertUUIDRaw() throws SQLException, DecoderException {
-
System.out.println("測試UUID RAW:");
-
long start = System.currentTimeMillis();
-
long end;
-
Connection con = DriverManager.getConnection(URL, USERNAME, PWD);
-
con.setAutoCommit(false);
-
PreparedStatement ps = con.prepareStatement("insert into test_uuid_raw(t_id) values(?)");
-
for (int i = 0; i < COUNT; i++) {
-
if (i == _1W) {
-
end = System.currentTimeMillis();
-
System.out.println("1W:" + (end - start));
-
} else if (i == _1W * 10) {
-
end = System.currentTimeMillis();
-
System.out.println("10W:" + (end - start));
-
} else if (i == _1W * 20) {
-
end = System.currentTimeMillis();
-
System.out.println("20W:" + (end - start));
-
} else if (i == _1W * 50) {
-
end = System.currentTimeMillis();
-
System.out.println("50W:" + (end - start));
-
} else if (i == _1W * 80) {
-
end = System.currentTimeMillis();
-
System.out.println("80W:" + (end - start));
-
}
-
-
byte[] data = Hex.decodeHex(UUID.randomUUID().toString().replaceAll("-", "").toCharArray());
-
ps.setBytes(1, data);
-
ps.addBatch();
-
-
if (i % (10 * _1W) == 0) {
-
ps.executeBatch();
-
}
-
}
-
ps.executeBatch();
-
con.commit();
-
ps.close();
-
con.close();
-
-
end = System.currentTimeMillis();
-
System.out.println("100W:" + (end - start));
-
}
-
-
public static void main(String[] args) throws ClassNotFoundException, SQLException, DecoderException {
-
Class.forName("oracle.jdbc.OracleDriver");
-
insertSeq();
-
insertUUID();
-
insertUUIDRaw();
-
}
- }
1w | 10w | 20w | 50w | 80w | 100w | |
序列 | 939 | 949 | 1584 | 3847 | 7732 | 12010 |
UUID Varchar2 | 2196 | 2915 | 14591 | 107528 | 861084 | 3051716 |
UUID RAW | 607 | 1237 | 9302 | 37817 | 169935 | 986043 |
不同的主鍵方案,不僅對索引維護有效能影響,同時也對索引的使用造成影響。(UUID作為主鍵索引的value佔用空間比序列大很多)。
同樣的查詢需求,都使用了主鍵索引,但是採用UUID作為主鍵,他的物理讀和一致性讀都遠遠超過了採用序列的情況。
所以如果沒有分散式環境的需求(例如層級資料上報),可以儘量採用序列作為主鍵。
單純就插入效能而言,序列>UUID RAW>UUID Varchar2
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1066263/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- css屬性的選擇對動畫效能的影響CSS動畫
- 修改主機時區對Oracle的影響分析Oracle
- mysql event對主從的影響MySql
- 影響rest api版本選擇的因素RESTAPI
- Kudu主鍵選擇策略
- myBatis插入oracle獲取主鍵MyBatisOracle
- 【OPTIMIZATION】Oracle影響優化器選擇的相關技術Oracle優化
- 如何在Oracle表中選擇主鍵列BWOracle
- 表資料量影響MySQL索引選擇MySql索引
- 主庫resetlogs對備庫的影響
- 【Oracle】-【COMMIT對索引的影響】-從trace看COMMIT對索引的影響OracleMIT索引
- 完美主義對新手程式設計師的影響程式設計師
- [非常急] js 語句無法對下拉選擇框產生影響的問題JS
- 修改系統時間對oracle的影響Oracle
- 「性別選擇」在遊戲中產生了哪些影響?遊戲
- Oracle 外來鍵索引影響阻塞問題Oracle索引
- 人工智慧對人類有哪些影響 選擇Python入門怎樣人工智慧Python
- 虛擬主機對網站有哪些影響?網站
- oracle點陣圖索引對DML操作的影響Oracle索引
- 磁碟排序對Oracle資料庫效能的影響排序Oracle資料庫
- GPFS Persistent Reserve 的設定對Oracle RAC 的影響Oracle
- gcc常用的編譯選項對程式碼的影響(轉)GC編譯
- 影響網頁渲染的關鍵!網頁
- 新特性:/dev/shm對Oracle 11g的影響devOracle
- 【Dataguard】Oracle多租戶環境對Dataguard的影響Oracle
- 磁碟排序對Oracle資料庫效能的影響PT排序Oracle資料庫
- 【Oracle】-【ROWNUM與索引】-索引對ROWNUM檢索的影響Oracle索引
- oracle cardinality對於執行計劃的影響Oracle
- oracle實驗記錄 (predicate對cpu cost的影響)Oracle
- 選擇排序和插入排序排序
- 物料主資料中日期對MRP影響測試
- mysql innodb 主鍵INT、BIGINT、VARCHAR併發插入效能對比MySql
- shrink 操作對索引的影響索引
- Update操作對索引的影響索引
- SQL最佳化-關於ORDERED-HASH中錯誤選擇連線欄位對效能的影響SQL
- MyBatis + MySQL返回插入成功後的主鍵idMyBatisMySql
- Oracle 11g 測試停庫對job的影響Oracle
- Oracle 物化檢視快速重新整理對效能的影響Oracle