数据库查询性能优化之利器—索引(一)

简介:

  数据库查询性能优化之利器—索引(一)

  最近在做基于Android的公交查询系统的过程中,遇到一个很棘手的问题:换乘算法效率低。在直达查询和一次换乘查询的时候,问题体现的还不是很明显,能够在1s之内查询出乘车方案,而当进行二次查询的时候,基本要等一两分钟才能查询出换乘方案,这对于公交查询系统是绝对无法容忍的。于是找了大量的关于公交换乘算法方面的论文和资料进行研究,发现大多治标不治本,没有从根本上解决公交换乘算法效率低下的问题。公交换乘算法主要有以下三种思路:

  1)基于数据库的查询;

  2)采用Dijkstra或者Floyd算法或者改进的Dijkstra算法;

  3)基于矩阵的运算;

  由于在做这个系统之前就想过这个问题,是采用Dijkstra算法、矩阵运算还是基于数据库的查询。仔细分析之后还是选择了基于数据库的查询,因为对于大中型城市的公交网络,Dijkstra算法和矩阵运算根本不适用,尤其还是基于Android系统的公交查询系统(离线查询系统),举个例子,像成都市的公交网络系统有将近500条公交线路,5000个公交站点,如果采用矩阵运算或者Dijkstra算法的话,就只是直达矩阵就得有5000*5000=25000000个数据,若数据采用int类型保存,则该矩阵得占用25000000*4/(1024*1024*8)=12M的内存空间,这个数据对于移动设备来说想而知,是不可取的办法。因此最后采用了基于数据库查询的方案。

  在我的数据库中有两张表:cnbusw(线路表),cnbus(站点线路表)

     cnbusw的字段:

     id:线路编号,busw:线路名称,shijian:起始站和起始时间描述;

     cnbus的字段:

  zhan:站点名,xid:对应的线路编号,pm:在该线路中的位置,kind:线路类型(去程or返程or环形路线)

  后来发现在进行一次换乘查询的时候需要直达站点信息,因此添加了一个视图direct

  direct的字段:

  start:起始站,end:终点站,route:对应的线路编号,stopcount:两站之间的站点数

  在数据库中进行测试了一下:

  1)直达方案的话,直接在direct中进行查询:

   比如下面一条sql查询语句:

select * from direct where start='磨子桥' and end='春熙路南口'

     查询耗时:119.05ms

  2)一次换乘查询方案,通过direct的自连接进行查询:

     比如下面一条sql查询语句:

select s1.start as start,s1.route as route1,s1.end as zhuan,s2.route as route2,
s2.end as end,s1.stopcount as count1,s2.stopcount as count2,(s1.stopcount+s2.stopcount) 
as stopcount from direct s1,direct s2 where s1.start='崔家店' and s2.end='磨子桥' and 
s1.end=s2.start and s1.route!=s2.route order by (s1.stopcount+s2.stopcount)

     查询耗时:415.32ms

  上述查询时间都在能够接受的范围之内,然后我很自然地按照上面的思路写出了三次换乘的sql查询语句,结果在查询时发现等了一分钟还没等出结果,并且sqlite可视化管理工具界面卡死了,这个很明显地告诉我二次换乘直接使用这样的sql语句是绝对不可行的,于是我想了一些办法,比如:两次换乘相当于是A->B->C->D,那么先查询经过站点D的线路中站点序号比D小的站点集合U,然后就相当于查询A到U集合中所有站点的一次换乘查询,这样就方便了,但是用sql语句查询了一下,一般U集合的大小都在400左右,然后要进行400次一次换乘查询,耗时400ms*400=160000ms=160s,怎么也得2分多钟,显然不可取。在陷入了这样的僵局之后,想了很久没想到办法,因为数据库里面的数据量很大,简单地对sql语句进行改进无法解决根本性问题。只有从数据库本身着手,于是想到了索引,以前上数据库课程的时候,老师提到过索引对于大量数据查询的时候效率提升的很明显,于是就尝试了一下,发现查询耗时一下减少了很多。在建立索引的过程中,原本想在视图上建立索引,发现似乎sqlite不支持在视图上创建索引,于是删除了direct视图,建立了direct直达表,在建立索引的时候,考虑是建立多列索引还是单列索引,分析一次换乘查询发现要将start,end,route这三列同时作为查询条件,并且要对stopcount进行排序,因此选择创建多列索引:

create index directindex on direct(start,end,route,stopcount)

  在创建索引之后,重新将上面的一次换乘查询语句执行了一次,耗时:5.59ms,查询速度提升了将近80倍,然后又将直达查询语句执行了一次,耗时0.49ms,也明显提升了不少。然后按照一次换乘的思路写出了二次换乘的sql语句进行执行,

select s1.start as start,s1.xid as route1,s1.end as zhuan1,s2.xid as route2 ,
s2.end as zhuan2,s3.xid as route3,s3.end as end,s1.stopcount,s2.stopcount,s3.stopcount,
(s1.stopcount+s2.stopcount+s3.stopcount) from direct s1,direct s2,direct s3 where 
s1.start='川大路黄河路口' and s3.end='春熙路南口' and s1.end=s2.start and s2.end=s3.start 
and s1.xid!=s2.xid and s2.xid!=s3.xid order by s1.stopcount+s2.stopcount+s3.stopcount

  耗时411.15ms,很好地解决查询效率低下的问题,从这里可以看出,在数据量很大的情况,建立索引和没有索引的区别简直是天壤之别,适当地建立索引能够使查询速度提升很大,关于索引的相关问题准备在后面进行进一步学习和研究。

 

本文转载自海 子博客园博客,原文链接:http://www.cnblogs.com/dolphin0520/archive/2012/08/25/2655587.html如需转载自行联系原作者


相关文章
|
4月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
175 4
|
5月前
|
人工智能 安全 机器人
无代码革命:10分钟打造企业专属数据库查询AI机器人
随着数字化转型加速,企业对高效智能交互解决方案的需求日益增长。阿里云AppFlow推出的AI助手产品,借助创新网页集成技术,助力企业打造专业数据库查询助手。本文详细介绍通过三步流程将AI助手转化为数据库交互工具的核心优势与操作指南,包括全场景适配、智能渲染引擎及零代码配置等三大技术突破。同时提供Web集成与企业微信集成方案,帮助企业实现便捷部署与安全管理,提升内外部用户体验。
616 12
无代码革命:10分钟打造企业专属数据库查询AI机器人
|
7月前
|
Cloud Native 关系型数据库 分布式数据库
|
8月前
|
存储 关系型数据库 分布式数据库
登顶TPC-C|云原生数据库PolarDB技术揭秘:单机性能优化篇
阿里云PolarDB云原生数据库在TPC-C基准测试中,以20.55亿tpmC的成绩打破性能与性价比世界纪录。此外,国产轻量版PolarDB已上线,提供更具性价比的选择。
|
7月前
|
并行计算 关系型数据库 MySQL
如何用 esProc 将数据库表转储提速查询
当数据库查询因数据量大或繁忙变慢时,可借助 esProc 将数据导出为文件进行计算,大幅提升性能。以 MySQL 的 3000 万行订单数据为例,两个典型查询分别耗时 17.69s 和 63.22s。使用 esProc 转储为二进制行存文件 (btx) 或列存文件 (ctx),结合游标过滤与并行计算,性能显著提升。例如,ctx 并行计算将原查询时间缩短至 0.566s,TopN 运算提速达 30 倍。esProc 的简洁语法和高效文件格式,特别适合历史数据的复杂分析场景。
|
4月前
|
SQL Java 应用服务中间件
数据库连接池详解及性能优化趋势
Sharding-JDBC所构建的Database Mesh与Service Mesh相互独立,协同工作。服务间的交互由Service Mesh Sidecar负责管理,而基于SQL的数据库访问则交由Sharding-JDBC-Sidecar处理。业务应用无需关心物理部署细节,实现真正的零侵入。Sharding-JDBC-Sidecar与宿主机生命周期绑定,非静态IP,确保了动态和弹性。尽管如此,数据运维操作仍可通过启动Sharding-JDBC-Server进程作为静态IP入口,借助命令行或UI客户端轻松完成。
|
5月前
|
存储 算法 关系型数据库
数据库主键与索引详解
本文介绍了主键与索引的核心特性及其区别。主键具有唯一标识、数量限制、存储类型和自动排序等特点,用于确保数据完整性和提升查询效率;而索引通过特殊数据结构(如B+树、哈希)优化查询速度,适用于不同场景。文章分析了主键与索引的优劣、适用场景及工作原理,并对比两者在唯一性、数量限制、功能定位等方面的差异,为数据库设计提供指导。
|
8月前
|
SQL 关系型数据库 MySQL
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
|
8月前
|
数据库
【YashanDB知识库】数据库用户所拥有的权限查询
【YashanDB知识库】数据库用户所拥有的权限查询

热门文章

最新文章