财务平台进行分录分表以后,随着数据量的日渐递增,业务人员对账务数据的实时分析响应时间越来越长,体验性慢慢下降,之前我们基于mysql的性能优化做了一遍,可以说基于mysql该做的优化已经基本上都做了,本次是基于elasticsearch对其做进一步的性能优化

正文

1mysql索引原理

基于mysql最常用也最直接有效的性能优化也就是添加索引。

mysql索引是怎么实现的呢?数据库最基本的查询算法是顺序查找,时间复杂度为O(n),显然在数据量很大的时候很低,优化的查询算法有二分查找,二叉树查找,虽然查找效率提高了,但是各自对检索的数据都有要求,二分查找检索被要求数据是有序的,而二叉树查找只能用于二叉树上,但是数据本身的组织结构不可能完全满足各种数据结构,例如,理论上不可能同时将两列都按顺序进行组织,所以在数据之外,数据库系统还维护者满足特定查找算法的数据结构,这些数据结构以某种方式引用数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

索引是什么?索引是存储引擎用于快速找到记录的一种数据结构,这是索引的基本功能,主要基于hash,b+tree。

我们开发当中一般用到都是mysql innoDB引擎,采用的是b+tree。

b+tree的优势主要体现在查询性能上,在单元素查询时,b+tree会自顶层向下逐层查找节点,最终找到我们需要的叶子节点,范围查询时,b+tree找到叶子节点的起始位置,通过叶子节点链表依次查询数据,直到范围结束为止。

参考上面的示意图

总结:基于b+tree的mysql索引,当这个树的形状瘦低的时候查询效率就会很快,因为查找磁盘的io次数很少,但是如果这个树的形状胖高的时候,查询磁盘的次数就会比较多,那么查询效率就会越来越慢,所以基于mysql索引的性能优化,索引是有限制的,适量的添加索引会对查询效率有明显提升,但是索引过量就适得其反,不但查询效率会降低,也会影响其他操作的效率,因为其他操作的时候也是需要维护索引的。

1elasticsearch索引原理

elasticsearch底层是索引原理是倒排索引,使用场景一般是OLAP,支持rest风格json数据格式交互的全文检索引擎,开源,面向文档设计,实时检索,索引可以无限扩展,只要你的服务器的磁盘、内存足够大。

我们先看一个列子

一个字段有一个自己的倒排索引。18,20这些叫做term,而[1,3]就是postinglist。Posting list就是一个int的数组,存储了所有符合某个term的文档id。

term Dictionary

term排序后的集合,方便二分查找,有了term Dictionary之后就可以在磁盘上查找到具体的document,磁盘的读操作非常昂贵,一次大概需要10ms时间,不同存储方式的磁盘性能不一样,所以为了减少磁盘的读取次数就必要把一些数据缓存到内存中,但是term Dictionary会有很多,不能完整的放到内存中,于是就有了termindex

term index

可以理解为就是英文词典的目录,它是一棵树的结构

示意图

这棵树不会包含所有的term,它只包含term的一些前缀,通过term index可以快速地定位到term dictionary的某个offset,然后从这个位置再往后顺序查找,大大减少了磁盘访问次数

示意图

所以term index不需要存下所有的term,而仅仅是他们的一些前缀与Term Dictionary的block之间的映射关系,再结合FST(Finite StateTransducers)的压缩技术,可以使term index缓存到内存中

为什么elasticsearch比mysql快

mysql只有 termdictionary这一层,是以树的方式存储在磁盘上的。检索一个term需要若干次的磁盘访问操作,而elasticsearch,在term dictionary的基础上添加了term index来加速检索,term index以树的形式缓存在内存中。从term index查到对应的term dictionary的block位置之后,再去磁盘上找term,大大减少了磁盘的访问次数。

term index在内存中是以FST的形式保存的,其特点是非常节省内存。Term dictionary在磁盘上是以分block的方式保存的,一个block内部利用公共前缀压缩,比如都是Ab开头的单词就可以把Ab省去。这样term dictionary可以更节约磁盘空间。

压缩技术

用FST压缩term index之外,对posting list也有压缩。

联合索引查询

以上都是单field索引,如果多个field索引的联合查询,比如查询age=18 AND gender=女,倒排索引如何满足快速查询的要求呢?大致过程如下:根据过滤条件 age=18 的先从term index找到18在term dictionary的大概位置,然后再从term dictionary里精确地找到18这个term,然后得到一个posting list或者一个指向posting list位置的指针。然后再查询gender=女的过程也是类似的。最后得出age=18 AND gender=女,就是把两个 posting list做一个“与”的合并

1、skip list

2、bitset 二进制,直接按位与

总结

elasticsearch就是尽量将磁盘里的东西搬进内存,减少磁盘随机读取次数(同时也利用磁盘顺序读特性),结合各种压缩算法,高效使用内存,从而达到快速搜索的目的。

1mysql索引与elasticsearch索引对比

mysql

如果数据量不是特别大,在千万级别,适当的管理好索引,查询效率还是可以的,但是对索引命中率有要求,就是必须要保证索引的命中率,还有就是索引的数量限制好,但是查询条件比较多、需要添加很多索引的时候mysql索引就有瓶颈了。

elasticsearch

使用了OLAP场景,海量数据实时查询,亿级以上数据量,因为底层采用的是倒排索引机制,只要你的服务器资源足够好,理论上随着数据量的增加、索引的增量,实时查询效率是线性的。

倒排索引

倒排索引应用场景:搜索引擎、实时排名,如百度搜索,搜狗搜索

索引分为正向索引和反向索引(倒排索引)

正向索引:通过Key找Value

正向索引的结构如下:

   “文档1”的ID > 单词1:出现次数,出现位置列表;单词2:出现次数,出现位置列表;…………。

   “文档2”的ID > 此文档出现的关键词列表。
  • 1
  • 2
  • 3

倒排索引:通过Value找Key

倒排索引的结构如下:

   “关键词1”:“文档1”的ID,“文档2”的ID,…………。

   “关键词2”:带有此关键词的文档ID列表。
  • 1
  • 2
  • 3

对应的倒排列表为:{(3;1;<4>),(5;1;<4>)},其含义为在文档3和文档5出现过这个单词,单词频率都为1,单词“拉斯”在两个文档中的出现位置都是4,即文档中第四个单词是“拉斯”。

倒排索引可以统计文档ID,出现次数,出现位置。

转载自:https://mp.weixin.qq.com/s/IfjwPEP5RjkfDt-VKSE2gg

财务平台亿级数据量毫秒级查询优化之elasticsearch原理解析的更多相关文章

  1. Elasticsearch如何做到亿级数据查询毫秒级返回?

    阅读本文大概需要 6 分钟. 如果面试的时候碰到这样一个面试题:ES 在数据量很大的情况下(数十亿级别)如何提高查询效率? 这个问题说白了,就是看你有没有实际用过 ES,因为啥?其实 ES 性能并没有 ...

  2. Mongodb亿级数据量的性能测试

    进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目:   (所有插入都是单线程进行,所有读取都是多线程进行) 1) 普通插入性能 (插入的数据每条大约在1KB左右) 2) 批量插入性能 ...

  3. 分库代价高的情况下,如何优化ES解决亿级数据量检索

    数据平台已迭代三个版本,从一开始遇到很多常见的难题,到现在终于有片段时间整理一些已完善的文档,在此分享以供所需朋友的实现参考,但愿能帮助大家少走些弯路,在此篇幅中偏重于ElasticSearch的优化 ...

  4. 查询亿级数据毫秒级返回!Elasticsearch 是如何做到的?

    掌握搜索技能,才能在庞大的数据集中找到准确的目标.本篇就带你进入另一个非凡的旅程,即使你没有像Google或Baidu一样强大的技术,一样也可以做出与之相匹敌的用户体验. 搜索是现代软件必备的一项基础 ...

  5. 数据库选型之亿级数据量并发访问(MySQL集群)

    刘 勇  Email:lyssym@sina.com 简介 针对实际应用中并发访问MySQL的场景,本文采用多线程对MySQL进行并发读取访问,其中以返回用户所需的数据并显示在终端为测试结束节点,即将 ...

  6. SQL优化(SQL TUNING)之10分钟完成亿级数据量性能优化(SQL调优)

    前几天,一个用户研发QQ找我,如下: 自由的海豚. 16:12:01 岛主,我的一条SQL查不出来结果,能帮我看看不? 兰花岛主 16:12:10 多久不出结果? 自由的海豚 16:12:17 多久都 ...

  7. SQL优化(SQL TUNING)之10分钟完毕亿级数据量性能优化(SQL调优)

    前几天.一个用户研发QQ找我,例如以下: 自由的海豚. 16:12:01 岛主,我的一条SQL查不出来结果,能帮我看看不? 兰花岛主 16:12:10 多久不出结果? 自由的海豚 16:12:17 多 ...

  8. Python 操作 mongodb 亿级数据量使用 Bloomfilter 高效率判断唯一性 例子

    工作需要使用 python 处理 mongodb 数据库两亿数据量去重复,需要在大数据量下快速判断数据是否存在 参考资料:https://segmentfault.com/q/101000000061 ...

  9. 挑战海量数据:基于Apache DolphinScheduler对千亿级数据应用实践

    点亮 ️ Star · 照亮开源之路 GitHub:https://github.com/apache/dolphinscheduler 精彩回顾 近期,初灵科技的大数据开发工程师钟霈合在社区活动的线 ...

随机推荐

  1. [FTP]通过FileZilla在阿里云主机上搭建ftp服务器

    前一阵子租了一台服务器主机来玩,正好周末有时间研究了一下怎么搭建ftp server. 准备.首先要下载filezilla client和filezilla server, 下载地址: server: ...

  2. c++11の关联容器

    一.关联容器 C++的容器类型可以分为顺序容器和关联容器两大类.对于关联容器,主要有map和set,对于这两种,根据不同的维度,衍生出了8种容器 map                        ...

  3. 使用axios 的post请求下载文件,

    axios({ method: 'post', data: param, responseType:'blob', url: _urls + '/Downloaddata' }).then(data= ...

  4. 禁止Cnario Player启动后自动开始播放

    Cnario Player安装激活后, 默认开机后自动启动, 启动加载内容完成后进入10秒倒计时, 10秒后即开始播放关机前播放的内容. 如果不想让其自动开始播放, 可按照如下办法设置其不自动播放. ...

  5. flutter-开发总结

    ### 上拉加载下拉刷新 ``` import 'dart:async'; import 'package:flutter_easyrefresh/easy_refresh.dart'; import ...

  6. Flex弹性布局以及box-sizing

    (本篇内容代表本人理解,如有错误请指出!) box-sizing box-sizing 属性用于更改用于计算元素宽度和高度的默认的 CSS 盒子模型.可以使用此属性来模拟不正确支持CSS盒子模型规范的 ...

  7. CentOS7安装MySQL8.0图文教程

    1.下载 MySQL 所需要的安装包 网址:https://dev.mysql.com/downloads/mysql/ 2.Select Operating System: 选择 Red Hat , ...

  8. dataframe常用处理

    获取列名:data.columns.values.tolist() 复制列: out['serial_number'] = out['2']这样就是新增了一列,复制了‘2’这一列,然后再del out ...

  9. python 第三方库的加载与虚拟机的登录

    通过pip来安装python模块(pip方式仅需要联网即可,不需要下载其他文件即可实现扩展库哦的安装.升级和卸载).下载python3.5以上的版本(包括3.5),在我的电脑输入cmd进入命令提示符, ...

  10. 在centos安装MySql的三种安装方法

    一.二进制安装MySql 1. 下载Mysql安装包 wget https://downloads.mysql.com/archives/get/file/mysql-5.6.40-linux-gli ...