在sqlite中使用索引
出处: 网络
1)Sqlite不支持聚集索引,android默认需要一个_id字段,这保证了你插入的数据会按“_id”的整数顺序插入,这个integer类型的主键就会扮演和聚集索引一样的角色。所以不要再在对于声明为:INTEGER PRIMARY KEY的主键上创建索引。
2)很多对索引不熟悉的朋友在表中创建了索引,却发现没有生效,其实这大多数和我接下来讲的有关。对于where子句中出现的列要想索引生效,会有一些限制,这就和前导列有关。所谓前导列,就是在创建复合索引语句的第一列或者连续的多列。比如通过:CREATE INDEX comp_ind ON table1(x, y, z)创建索引,那么x,xy,xyz都是前导列,而yz,y,z这样的就不是。下面讲的这些,对于其他数据库或许会有一些小的差别,这里以sqlite为标准。在where子句中,前导列必须使用等于或者in操作,最右边的列可以使用不等式,这样索引才可以完全生效。同时,where子句中的列不需要全建立了索引,但是必须保证建立索引的列之间没有间隙。举几个例子来看吧:
用如下语句创建索引:
CREATE INDEX idx_ex1 ON ex1(a,b,c,d,e,...,y,z);
这里是一个查询语句:
...WHERE a=5 AND b IN (1,2,3) AND c IS NULL AND d='hello'
这显然对于abcd四列都是有效的,因为只有等于和in操作,并且是前导列。
再看一个查询语句:
... WHERE a=5 AND b IN (1,2,3) AND c>12 AND d='hello'
那这里只有a,b和c的索引会是有效的,d列的索引会失效,因为它在c列的右边,而c列使用了不等式,根据使用不等式的限制,c列已经属于最右边。
最后再看一条:
... WHERE b IN (1,2,3) AND c NOT NULL AND d='hello'
索引将不会被使用,因为没有使用前导列,这个查询会是一个全表查询。
3)对于between,or,like,都无法使用索引。
如 ...WHERE myfield BETWEEN 10 and 20;
这时就应该将其转换成:
...WHERE myfield >= 10 AND myfield <= 20;
再如LIKE:...mytable WHERE myfield LIKE 'sql%';;
此时应该将它转换成:
...WHERE myfield >= 'sql' AND myfield < 'sqm';
再如OR:...WHERE myfield = 'abc' OR myfield = 'xyz';
此时应该将它转换成:
...WHERE myfield IN ('abc', 'xyz');
其实除了索引,对查询性能的影响因素还有很多,比如表的连接,是否排序等。影响数据库操作的整体性能就需要考虑更多因素,使用更对的技巧,不得不说这是一个很大的学问。
最后在android上使用sqlite写一个简单的例子,看下索引对数据库操作的影响。
创建如下表和索引:
db.execSQL("create table if not exists t1(a,b)");
db.execSQL("create index if not exists ia on t1(a,b)");
插入10万条数据,分别对表进行如下操作:
select * from t1 where a='90012'
插入:insert into t1(a,b) values('10008','name1.6982235534984673')
更新:update t1 set b='name1.999999' where a = '887'
删除:delete from t1 where a = '1010'
数据如下(5次不同的操作取平均值):
操作 无索引 有索引
查询 170ms 5ms
插入 65ms 75ms
更新 240ms 52ms
删除 234ms 78ms
可以看到显著提升了查询的速度,稍稍减慢了插入速度,还稍稍提升了更新数据和删除数据的速度。如果把更新和删除中的where子句中的列换成b,速度就和没有索引一样了,因为索引失效。所以索引能大幅度提升查询速度,对于删除和更新操作,如果where子句中的列使用了索引,即使需要重新build索引,有可能速度还是比不使用索引要快的。对与插入操作,索引显然是个负担。同时,索引让db的大小增加了2倍多。
在sqlite中使用索引的更多相关文章
- MySql SqlServer Sqlite中关于索引的创建
最近要更新Cocon90.Db库,令其ORM创建表时实现索引的添加.因此总结下列常用Sql,供大家学习与参考. 一.SqlServer中创建索引可以这样: ) Create Table Test ( ...
- 在SQLite中使用索引优化查询速度
在进行多个表联合查询的时候,使用索引可以显著的提高速度,刚才用SQLite做了一下测试. 建立三个表: create table t1 (id integer primary key,num inte ...
- 谈数据库索引和Sqlite中索引的使用
要使用索引对数据库的数据操作进行优化,那必须明确几个问题:1.什么是索引2.索引的原理3.索引的优缺点4.什么时候需要使用索引,如何使用围绕这几个问题,来探究索引在数据库操作中所起到的作用. 1.数据 ...
- SQLite 中的各种限制
英文原文:Limits In SQLite 本文定义了 SQLite 的限制,如何针对这些限制定制特定的应用程序.默认的限制设置通常是适当的,几乎适合于每一个应用.有一些应用程序可能需要在 ...
- 在Sqlite中通过Replace来实现插入和更新
你可能在批量处理一个事务的时候,想要批量插入一系列的数据,但是这些数据当添加完一次之后,重新添加的时候,你不想要重新添加,只是想将原有的数据进行更新,例如:我想要通过Excel将一系列的图书导入到 ...
- 解析SQLite中的常见问题与总结详解
1. 创建数据如果不往数据库里面添加任何的表,这个数据库等于没有建立,不会在硬盘上产生任何文件,如果数据库已经存在,则会打开这个数据库. 2. 如何通过sqlite3.dll与sqlite3.def生 ...
- SQLite中字段顺序和PAGE_SIZE对性能的影响
1.背景 SQLite数据库中有1张表,该表含若干个字段,其中有1个字段为BLOB类型,且BLOB字段不是最后1个字段.表结构类似如下(col3为BLOB字段): T (col1 INTEGER,co ...
- EF6 在 SQLite中使用备忘
== 菜鸟级选手试验在EF6中使用Sqlite,零EF基础,少量Sqlite基础.经过断断续续的很长时间 - _ -! >>连接 1. 安装 使用目前最新版本EF6.1,Sqlite1.0 ...
- java中的泛型和sql中的索引
sql中的索引 索引:好处查询的速度快,被删除,修改,不会对表产生影响,作用是加速查询: 一种典型的数据库对象 作用:提交数据的查询效率,尤其对一些数据量很大的表 索引是用来为表服务的 索引是orac ...
随机推荐
- html系列教程--span style 及表格标签 title video
<span> 标签:非块状元素,用于文本描述 <style> 标签:内联样式表标签定义样式信息,必须写明type类型为text/css,建议写在head中,不是必须 demo: ...
- node.js(八) 有趣的东西才开始哦
### Express介绍 npm提供了大量的第三方模块,其中不乏许多Web框架,比如我们本章节要讲述的一个轻量级的Web框架 ——— Express. Express是一个简洁.灵活的node.js ...
- How to close existing connections to a DB
use master ALTER DATABASE YourDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE --do you stuff here A ...
- Oracle学习之Oracle 树操作(select…start with…connect by…prior)
转自:http://www.cnblogs.com/linjiqin/archive/2013/06/24/3152674.html oracle树查询的最重要的就是select…start with ...
- typedef的用法总结
typedef的用法总结 不管实在C还是C++代码中,typedef这个词都不少见,当然出现频率较高的还是在C代码中.typedef与#define有些相似,但更多的是不同,特别是在一些复杂的用法上, ...
- KETTLE使用入门
一.准备文件 1.安装java虚拟机 2.安装kettle安装文件 二.使用步骤 1.点击Spoon.bat,启动kettle,弹出DOS窗口如下: 2.进入主界面 3.新建资源库
- 几种改变Activity回退栈默认行为的Intent Flag
FLAG_与LaunchMode相比最大的不同是临时性 1.FLAG_ACTIVITY_NEW_TASK: Developer.android.com的说法: (1)在新的task中启动这个Activ ...
- java.sql.ResultSetMetaData.getColumnLabel和getColumnName的区别
如果将ResultSet的结果映射到HashMap中,要使用getColumnLabel,而不要用getColumnName,这样可提高程序的健壮性 理由: getColumnName返回的是sql语 ...
- Linux c 信号量
信号量(通过进程通信实现进程间的同步) 信号量(semaphore)信号灯 信号量是共享内存整数数组.根据需要定义指定的数组长度 信号量就是根据数组中的值,决定阻塞还是解除阻塞 编程模型: 1. ...
- 利用OpenCV和MFC对话框建设一个有滑动条控制的播放器--转
(一)问题的提出: OpenCV有一个很简单的播放视频文件并加载滑动条的程序,但是如何用MFC对话框来创建一个有滑动条控制的播放器呢,网络上四处搜索都没有代码可以参考,下的都是些骗子链接文件,很过分, ...