You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MySQL性能反超Redis?基准测试异常问题求助

为啥查询100条记录时MySQL比Redis快?

嘿,这个问题确实有点反直觉——按说Redis作为内存数据库,小批量数据查询应该比MySQL快才对,咱们一步步拆解可能的原因,再给你些排查方向:

一、Redis操作模式的额外开销

你试的三种方案里,有些会天然带来更多的网络/命令开销:

  • 方案1(ID列表+哈希表):如果你是先LRANGE拿100个ID,再循环调用HGET逐个取JSON,那就是101次Redis命令请求(1次LRANGE+100次HGET),每次请求都要走TCP握手/往返,延迟累加起来就会比MySQL的单次查询拉100条慢很多。就算用HMGET批量获取,也要确保是把100个ID一次性传给HMGET,而不是拆分多次请求。
  • 方案3(有序集合):如果ZRANGE直接返回JSON数据,那开销应该和方案2类似,但如果还要额外处理分值排序、过滤逻辑,或者客户端对返回的有序集合做二次处理,也会增加耗时。

二、MySQL的缓存机制在“作弊”

MySQL的InnoDB Buffer Pool会把热数据缓存到内存里,如果你反复跑同一个查询,数据早就被加载到内存了,这时候MySQL的性能会无限接近内存数据库。甚至因为MySQL查询优化器对SQL的高效执行(比如索引覆盖查询),比Redis的多步操作更高效。

  • 你可以试试冷启动MySQL:先清空Buffer Pool(执行FLUSH TABLES WITH READ LOCK; UNLOCK TABLES;或者直接重启MySQL),再跑测试,看MySQL的耗时会不会明显上升。

三、Redis客户端/服务器的配置坑

  • 没开流水线(Pipeline):Redis默认是单命令单请求,如果你的客户端没开启Pipeline,100条记录的操作会产生多次TCP往返。试试把多个Redis命令打包到一个Pipeline里发送,比如:
    $client->pipeline(function ($pipe) use ($commentIds) {
        foreach ($commentIds as $id) {
            $pipe->hget('comment:hash', $id);
        }
    });
    
    这样能把多个请求合并成一次,大幅减少网络延迟。
  • Redis服务器的性能瓶颈:检查Redis的状态,执行INFO命令看看:
    • used_memory是不是远小于服务器内存?如果Redis用到了磁盘swap(看used_memory_rss远大于used_memory),性能会暴跌。
    • 有没有开启持久化(RDB/AOF)?如果测试时刚好赶上持久化快照生成或AOF刷盘,会暂时阻塞Redis。
    • 有没有evicted_keys不为0?说明内存不够,Redis在淘汰数据,这会严重影响查询速度。

四、序列化/反序列化的隐形开销

  • 如果Redis存的是JSON字符串,客户端每次查询后都要自己做反序列化(比如PHP里的json_decode),而MySQL 5.7+支持原生JSON字段,服务器端可以直接处理,甚至可以对JSON字段建索引,查询时不需要客户端额外处理。
  • 另外,Redis存储的JSON有没有冗余?比如额外的转义字符、包装格式,导致数据量比MySQL存储的更大,传输时间更长。

五、测试方法的问题

  • 控制变量没做好:测试时是不是同时跑了其他程序抢占资源?比如Redis和MySQL在同一台服务器上,CPU/内存被其他进程占用,影响了Redis的性能。
  • 测试次数太少:单次测试的波动很大,应该跑至少1000次查询,取平均耗时。
  • 时间统计不精准:有没有把客户端的处理时间(比如JSON解析、数据组装)也算进去?比如Redis的客户端如果在本地,MySQL也在本地,网络开销差不多,但如果Redis在远程服务器,那网络延迟会拖后腿。

排查步骤建议

  1. 单独测试Redis的单命令耗时:比如LRANGE list 0 99的耗时,再测HMGET hash id1 id2 ... id100的耗时,加起来和MySQL的SELECT * FROM comments LIMIT 100对比。
  2. 开启Redis Pipeline后再跑测试,看性能有没有提升。
  3. 冷启动MySQL后再测,对比热缓存下的耗时。
  4. redis-benchmark工具单独测Redis的命令性能,排除客户端的问题。

内容的提问来源于stack exchange,提问作者somejkuser

火山引擎 最新活动