缓存遇到的数据过滤与分页问题

遇到的问题

1、最初阶段

系统中做了一个监控功能,用于记录所有的请求数据,数据插入频繁,量非常大,比如一天1000万条。考虑到数据插入的效率,就使用内存KV缓存来保存。写入过程是在接收到请求后放入到线程池中,然后线程池异步处理后写入。到这问题基本上没什么事情。

2、新的需求

后面数据保存了,就需要在运维系统中可以查询到,所以这个缓存还必须是分布式的。于是就换成了redis,这样系统都可以连接到。但是数据量太大,需要分页查询,这就有点头痛了。还好redis是可以支持有序集合的,而且可以通过zrange来获取指定范围数据。

3、增加了需求

这些数据要在运维界面里还要可以按条件过滤,这个就非常头疼啦,redis没有条件过滤啊。即使过滤出来了数据要显示在界面上必须分页。

问题思考

最终突然发现如果存在数据库里是不是很好解决?但是存在数据库里就会有大量写操作的问题,而且数据这么大,像Mysql单表很容易就破了。所以我想着是不是还是在nosql的基础上解决。

这里就有几个问题:大数据量的排序、查找过滤、分页。

先不管这么多,如果使用Mysql的话,除了大表保存问题,查找、过滤、分页功能都是直接使用sql实现的,开发起来简单。

mysql

如果使用mysql存储后,如果要查一些数据怎么整?先看下面的这段代码:

SELECT t.* 
    from ofOffline1 t 
    ORDER BY t.creationDate desc
  LIMIT 1300000,100

这里最直接的就体现了两点:先排序,然后取分页的数据。好了,这里有几个问题:

1、使用了*返回字段,全字段返回的问题就是要扫描全表 2、进行了ORDERBY排序,我测试的这个表只有几百万数据 3、最后分页是取的130万开始的100条,等于是要扫描130万后才开始

我随便跑了一下执行了:5.5秒左右。有没有办法让它快一点呢?确实有,网上找找挺多的。

首先,看看只返回部分字段是不是快一些?

SELECT t.creationDate 
    from ofOffline1 t 
    ORDER BY t.creationDate desc
  LIMIT 1300000,100

上面的SQL语句,改造后,只返回一个字段,再执行。2.9秒了。

那么取1条数据的速度会不会快一些呢?

SELECT t.creationDate 
    from ofOffline1 t 
    ORDER BY t.creationDate desc
  LIMIT 1300000,1

执行上面的sql后发现时间还是2.9秒,这说明取1条的数据也是这么慢,那慢的肯定就是排序啦。

然后使用这一条取出来的数据作为条件,直接在集合中定位到分页数据

SELECT ofOffline1.* FROM ofOffline1 WHERE ofOffline1.creationDate <(
SELECT t.creationDate 
    from ofOffline1 t 
    ORDER BY t.creationDate desc
  LIMIT 1300000,1
) 
ORDER BY ofOffline1.creationDate desc
LIMIT 100

这是网上查到的SQL,思路就是先使用子查询定位到第130万条记录,然后从它开始取后面的99条。时间差不多3.9秒左右。这说明这样的优化还是有效的。

使用一下索引 我想了想如果加个索引是不是可以提升性能呢?SQL中只使用了creationDate排序和过滤,那么就用它建个索引试试吧。

还是测试一下最简单的那条SQL

SELECT t.* 
    from ofOffline1 t 
    ORDER BY t.creationDate desc
  LIMIT 1300000,100

结果是:5.5秒左右,没变化

那么看看前面有子查询的情况:

SELECT ofOffline1.* FROM ofOffline1 WHERE ofOffline1.creationDate <(
SELECT t.creationDate 
    from ofOffline1 t 
    ORDER BY t.creationDate desc
  LIMIT 1300000,1
) 
ORDER BY ofOffline1.creationDate desc
LIMIT 100

不错,执行结果:0.599秒。

好吧,本文先到这,后面再学习一下mangodb,按理它会比较适合我们的场景。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

索引列顺序导致的性能问题

今天和大家分享一个很有意思的例子,关于索引列的顺序导致的性能问题。 发现数据库的性能比较差,CPU消耗很高,抓了一个awr,发现瓶颈在sql上,top 1的sq...

3745
来自专栏深度学习之tensorflow实战篇

SQL:将查询结果插入到另一个表的三种情况

SQL:将查询结果插入到另一个表的三种情况 一:如果要插入目标表不存在: select * into 目标表 from 表 where … 二:如果要插入目标表...

3456
来自专栏数据库

记一次排查DB死锁的分析

文章摘要 在线上环境遇到数据库死锁问题该如何分析并解决问题呢? 虽然很多童鞋在学数据库课程时都了解数据库隔离级别、死锁和事务等概念,但在测试/线上环境遇到死锁却...

2318
来自专栏我和PYTHON有个约会

数据库连接引擎那点事儿

天长,地久。天地之所以能长且久者,以其不自生也,故能长生。是以圣人后其身而身先,外其身而身存,非以其无私邪?故能成其私。——老子

882
来自专栏CaiRui

Mysql-4-数据库的基本操作

1.创建数据库 create database database_name; 例:create database aa; show create databas...

1967
来自专栏杨建荣的学习笔记

MySQL误操作数据恢复的简单实践(r11笔记第67天)

前几天有个同事碰到了一个MySQL数据恢复的问题,他运行了一条update语句,结果忘记了加where条件,结果等反应过来已经晚了。我简单确认了下,是否...

4079
来自专栏听雨堂

Mysql高效插入/更新数据

从tushare抓取到的财务数据,最开始只是想存下来,用的办法想简单点,是:插入--报错—update 但发现这个方法太蠢,异常会导致大量无效连接,改为: ...

3197
来自专栏Java面试通关手册

MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇

Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_G...

2307
来自专栏大数据架构

SQL优化(六) MVCC PostgreSQL实现事务和多版本并发控制的精华

2355
来自专栏听雨堂

Mysql高效插入/更新数据

从tushare抓取到的财务数据,最开始只是想存下来,用的办法想简单点,是:插入--报错—update 但发现这个方法太蠢,异常会导致大量无效连接,改为: ...

2155

扫码关注云+社区

领取腾讯云代金券