最近在工作中,遇到到了sqlite主键类型选择的问题,于是就做个测试程序来测试sqlite采用UUID主键和int型自增主键性能对比。(本人时间有限,没有做多次测试,希望有人能帮着多测试一下)
1.sqlite采用UUID主键的优点和缺点。
缺点:UUID字符串长度太长,加大网络数据传输数据量。
2.sqlite采用int型自增主键的优点和缺点。
优点:int型主键字符串长度短,网络传输数据量不大。
3.测试环境
测试手机 | 三星Galaxy S3(i9300) |
安卓版本 | Android 4.3 (CM10.2) |
软件环境 | 已ROOT,杀掉全部后台服务 |
测试用例sqlite表结构
UUID主键:
[sql]
- createtablesysUserUUID(idTEXTPRIMARYKEY,uNameTEXT)
int自增主键:
[sql]
- createtablesysUserInt(idINTEGERPRIMARYKEYAUTOINCREMENT,uNameTEXT)
转换json工具包:gson-2.2.4.jar
4.测试结果
操作 | UUID主键 | int自增主键 | |
插入数据耗时 | 100条 | 1582ms | 1583ms |
500条 | 10308ms | 9496ms | |
读取数据耗时 | 100条 | 19ms | 25ms |
500条 | 58ms | 59ms | |
json字符串大小 | 100条 | 6.14kb | 2.62kb |
500条 | 31.14kb | 13.95kb |
5. 结论
根据测试数据我们可以得出以下结论:
1.sqlite只是简单的文件型数据库,没有对任何类型的主键进行优化,所以采用UUID和int自增主键没有本质上的性能差距,而我们测试中UUID比int主键稍微慢一点的原因我认为是uuid字符串太长。
2.用json传输数据时,每100条uuid的数据会比int型的大3.4kb左右,考虑到本测试中int型主键都是从1开始的,而实际应用中可能大于10000,故而他们的差距应该比3.4kb要小;如果再考虑做表关联时需要传输复合主键,那么int型的大小应该再大一些。考虑到一般读取数据不会超过100条,这个差距即使在2G的网络环境下对响应时间的影响也不到0.5秒。故而数据大小的区别可以忽略。
6. 附:主要测试类
[java]
- packagecom.zf.uuidtest;
- importjava.io.File;
- importjava.util.ArrayList;
- importjava.util.Date;
- importjava.util.List;
- importjava.util.UUID;
- importjavax.crypto.interfaces.PBEKey;
- importcom.example.uuidtest.R;
- importcom.google.gson.Gson;
- importandroid.os.Bundle;
- importandroid.os.Environment;
- importandroid.os.Handler;
- importandroid.app.Activity;
- importandroid.app.ProgressDialog;
- importandroid.database.Cursor;
- importandroid.database.sqlite.sqliteDatabase;
- importandroid.database.sqlite.sqliteOpenHelper;
- importandroid.util.Log;
- importandroid.view.Menu;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.widget.Button;
- importandroid.widget.EditText;
- importandroid.widget.ProgressBar;
- importandroid.widget.TextView;
- importandroid.widget.Toast;
- publicclassMainActivityextendsActivity{
- TextViewtvUUIDTitle;
- TextViewtvIntTitle;
- EditTextetTestIntCount;
- EditTextetTestUUIDCount;
- ButtonbtnStartTestUUID;
- ButtonbtnStartTestInt;
- TextViewtvUUIDRs;
- TextViewtvIntRs;
- ProgressBarpbInProgress;
- ButtonbtnStartLoadTestUUID;
- ButtonbtnStartLoadTestInt;
- intintTestCnt;
- intUUIDTestCnt;
- longintTestCost;
- longUUIDTestCost;
- FileUUIDFile;
- FileintFile;
- DatabaseUtildb;
- staticfinalintTEST_INT_MSG=11110;
- staticfinalintLOAD_INT_MSG=41110;
- staticfinalintTEST_UUID_MSG=11111;
- staticfinalintLOAD_UUID_MSG=41111;
- staticfinalintDONE_CNT_MSG=21111;
- staticStringAPP_DIR="test_sqlite";
- intdoneCnt;
- List<SysUserUUID>sysUserUUIDs;
- List<SysUserInt>sysUserInts;
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- db=newDatabaseUtil(this);
- db=db.open();
- db.executesql("droptableifexistssysUserInt");
- db.executesql("droptableifexistssysUserUUID");
- db.executesql("createtablesysUserInt(idINTEGERPRIMARYKEYAUTOINCREMENT,uNameTEXT)");
- db.executesql("createtablesysUserUUID(idTEXTPRIMARYKEY,uNameTEXT)");
- initView();
- }
- Handlerhandler=newHandler(){
- publicvoidhandleMessage(android.os.Messagemsg){
- pbInProgress.setVisibility(View.GONE);
- switch(msg.what){
- caseDONE_CNT_MSG:
- break;
- caseTEST_INT_MSG:
- StringintRs="插入耗时"+intTestCost+"ms";
- tvIntRs.setText(intRs);
- btnStartLoadTestInt.setEnabled(true);
- break;
- caseTEST_UUID_MSG:
- StringuuidRs="插入耗时"+UUIDTestCost+"ms";
- tvUUIDRs.setText(uuidRs);
- btnStartLoadTestUUID.setEnabled(true);
- break;
- caseLOAD_INT_MSG:
- Stringrs1=tvIntRs.getText().toString()+",读取耗时"
- +intLoadCost+"ms,json文件大小"+FileUtils.getFormatSize(intFile.length());
- tvIntRs.setText(rs1);
- break;
- caseLOAD_UUID_MSG:
- Stringrs=tvUUIDRs.getText().toString()+",读取耗时"
- +UUIDLoadCost+"ms,json文件大小"+FileUtils.getFormatSize(UUIDFile.length());
- tvUUIDRs.setText(rs);
- break;
- default:
- break;
- }
- };
- };
- voidinitView(){
- tvUUIDTitle=(TextView)findViewById(R.id.tvUUIDTitle);
- tvIntTitle=(TextView)findViewById(R.id.tvIntTitle);
- etTestIntCount=(EditText)findViewById(R.id.etTestIntCount);
- etTestUUIDCount=(EditText)findViewById(R.id.etTestUUIDCount);
- tvUUIDRs=(TextView)findViewById(R.id.tvUUIDRs);
- tvIntRs=(TextView)findViewById(R.id.tvIntRs);
- btnStartTestUUID=(Button)findViewById(R.id.btnStartTestUUID);
- btnStartTestInt=(Button)findViewById(R.id.btnStartTestInt);
- btnStartLoadTestUUID=(Button)findViewById(R.id.btnStartLoadTestUUID);
- btnStartLoadTestInt=(Button)findViewById(R.id.btnStartLoadTestInt);
- pbInProgress=(ProgressBar)findViewById(R.id.pbInProgress);
- btnStartTestInt.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- pbInProgress.setVisibility(View.VISIBLE);
- intTestCnt=Integer.parseInt(etTestIntCount.getText()
- .toString());
- newThread(){
- publicvoidrun(){
- try{
- longstart=newDate().getTime();
- for(inti=0;i<intTestCnt;i++){
- StringBuildersb=newStringBuilder(
- "insertintosysUserInt(uName)values('")
- .append("name").append(i).append("')");
- db.executesql(sb.toString());
- }
- longend=newDate().getTime();
- intTestCost=end-start;
- handler.sendEmptyMessage(TEST_INT_MSG);
- }catch(Exceptionex){
- ex.printStackTrace();
- }
- };
- }.start();
- }
- });
- btnStartTestUUID.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewv){
- pbInProgress.setVisibility(View.VISIBLE);
- UUIDTestCnt=Integer.parseInt(etTestUUIDCount.getText()
- .toString());
- newThread(){
- publicvoidrun(){
- try{
- longstart=newDate().getTime();
- for(inti=0;i<UUIDTestCnt;i++){
- StringBuildersb=newStringBuilder(
- "insertintosysUserUUID(id,uName)values('")
- .append(UUID.randomUUID())
- .append("','").append("name").append(i)
- .append("')");
- db.executesql(sb.toString());
- }
- longend=newDate().getTime();
- UUIDTestCost=end-start;
- handler.sendEmptyMessage(TEST_UUID_MSG);
- }catch(Exceptionex){
- ex.printStackTrace();
- }
- };
- }.start();
- }
- });
- btnStartLoadTestUUID.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewarg0){
- pbInProgress.setVisibility(View.VISIBLE);
- UUIDTestCnt=Integer.parseInt(etTestUUIDCount.getText()
- .toString());
- newThread(){
- publicvoidrun(){
- try{
- longstart=newDate().getTime();
- Stringsql="select*fromsysUserUUIDorderbyidlimit"
- +UUIDTestCnt+"offset0";
- Cursorcr=db.mDb.query("sysUserUUID",
- newString[]{"id","uName"},null,
- null,"idlimit"+UUIDTestCnt
- +"offset0");
- sysUserUUIDs=newArrayList<SysUserUUID>();
- while(cr.moveToNext()){
- SysUserUUIDsysUserUUID=newSysUserUUID();
- sysUserUUID.setId(cr.getString(0));
- sysUserUUID.setuName(cr.getString(1));
- sysUserUUIDs.add(sysUserUUID);
- }
- if(Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED)){
- StringdirStr=Environment
- .getExternalStorageDirectory()
- .getPath()
- +File.separator+APP_DIR;
- UUIDFile=newFile(dirStr+File.separator
- +"uuid.json");
- if(!UUIDFile.exists()){
- Filedir=newFile(UUIDFile.getParent());
- dir.mkdirs();
- UUIDFile.createNewFile();
- }
- Gsongson=newGson();
- FileUtils.writeFile(UUIDFile,
- gson.toJson(sysUserUUIDs).toString());
- }else{
- Toast.makeText(MainActivity.this,"sd卡错误",1)
- .show();
- }
- longend=newDate().getTime();
- UUIDLoadCost=end-start;
- handler.sendEmptyMessage(LOAD_UUID_MSG);
- }catch(Exceptione){
- e.printStackTrace();
- }
- };
- }.start();
- }
- });
- btnStartLoadTestInt.setOnClickListener(newOnClickListener(){
- @Override
- publicvoidonClick(Viewarg0){
- pbInProgress.setVisibility(View.VISIBLE);
- intTestCnt=Integer.parseInt(etTestIntCount.getText()
- .toString());
- newThread(){
- publicvoidrun(){
- try{
- longstart=newDate().getTime();
- Stringsql="select*fromsysUserIntorderbyidlimit"
- +intTestCnt+"offset0";
- Cursorcr=db.mDb.query("sysUserInt","idlimit"+intTestCnt
- +"offset0");
- sysUserInts=newArrayList<SysUserInt>();
- while(cr.moveToNext()){
- SysUserIntsysUserInt=newSysUserInt();
- sysUserInt.setId(cr.getInt(0));
- sysUserInt.setuName(cr.getString(1));
- sysUserInts.add(sysUserInt);
- }
- if(Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED)){
- StringdirStr=Environment
- .getExternalStorageDirectory()
- .getPath()
- +File.separator+APP_DIR;
- intFile=newFile(dirStr+File.separator
- +"int.json");
- if(!intFile.exists()){
- Filedir=newFile(intFile.getParent());
- dir.mkdirs();
- intFile.createNewFile();
- }
- Gsongson=newGson();
- FileUtils.writeFile(intFile,
- gson.toJson(sysUserInts).toString());
- }else{
- Toast.makeText(MainActivity.this,1)
- .show();
- }
- longend=newDate().getTime();
- intLoadCost=end-start;
- handler.sendEmptyMessage(LOAD_INT_MSG);
- }catch(Exceptione){
- e.printStackTrace();
- }
- };
- }.start();
- }
- });
- }
- longUUIDLoadCost;
- longintLoadCost;
- voidtestIntId(){
- }
- voidtestUUIDId(){
- }
- }