MySQL 数据上亿以后,查询分页问题

340 天前
 Features
查询分页一般要最少要执行两条 SQL 语句

` SELECT COUNT(*) FROM tablename WHERE columnName = 'xx' `
` SELECT * FROM tablename WHERE columnName = 'xx' limit 0,10`

因为查询条件是动态的,所以不太可能做缓存
这种情况应该是必须要分表了吧?
有什么数据库能在不分表,走索引的情况下实现良好的体验呢?
4899 次点击
所在节点    MySQL
40 条回复
changdy
340 天前
https://juejin.cn/post/7207410405786484796

https://juejin.cn/post/7323570678690185242

我自己做过一个订单查询的优化 ..场景复杂得多 .

不知道楼主是已经有了具体的场景,还是只是猜想将来的维护情况
Pythoner666666
340 天前
瓶颈在你这个 count(*),下面一条走索引不会慢,所以解决办法就是跟 PM 沟通下,要么把时间筛选加上,要么就加缓存允许一定的延迟。
vacuitym
340 天前
不然做一张表单纯存数据的 count ,然后去定时刷新
nice2cu
340 天前
limit 页数大了也会慢的, 试试业务上能不能处理下,比如必填条件数增多,分页量大时不然看 1000 页之后的
tonghuashuai
340 天前
数据量大以后使用 limit offset, size 会有性能问题,可以使用 id 作为 cursor 。
june4
340 天前
先确定有没有准确实时的大数据集总数这个需求吧
opengps
340 天前
我们这里要求的是分两步走:先执行第二句,有信息返回再执行第一句,否则第一句直接就用返回值 0 代替
JackCh3ng
340 天前
如果你的查询条件不复杂,数据量基本固定不会再增加,可以用缓存计数的方式,否则就乖乖上 es 吧,而且就算上 es 也还是解决不了深度分页的问题( es 只能查询一万条数据,也就是说 10 条一页,只能 1000 页,后面的也查不出来了)。如果觉得 es 成本太高,在没有复杂查询条件的情况下也可以尝试列式存储,但具体效率要看数据量和查询字段,使用列式存储仍然需要一个事务数据库,同样是需要数据同步的方案,或者在代码里进行双写。
silentsky
340 天前
如果是内部使用 换 olap 数据库,否则不要 count
zhuoyue100
340 天前
数据量比较大的时候,这类查询一般不走业务表,可以异步写一份到分析型数据库来实现
ShuA1
340 天前
别用 count 用 EXPLAIN ,快很多,测试一下吧
iyiluo
340 天前
最好和业务商量一下,看看能不能限制一下查询范围,例如对外展示的数据限制前面 100 页
FreeEx
340 天前
1. 非要有总数量的话就得加上一个时间范围的选择。
2. 不要总数量的话就可以用游标分页,这种需要数据结构中有一个字段是带顺序且唯一。

第二种可以参考 https://bojithapiyathilake.medium.com/pagination-offset-vs-cursor-in-mysql-92cbf1a02cfa
realNewBee
340 天前
如果想通过技术手段来解决,那就不能使用 MySQL ,得使用其他的数据库。否则只能通过业务方案来解决。
数据量超过百万,count 和 limit 都有性能问题。所以肯定不能用。在不改变数据库的情况下,我能想到的就是用 ID 来做滚动分页+索引搜索的业务方案来解决。
coderzhangsan
340 天前
上亿数据分页查询,楼上已经说明了存在的问题,我帮你简单汇总下:

1. innodb 引擎,count 查询会很慢,优化的重点将是这里。
a. 统计精度不精准的前提下,可以使用 explain select count(*) from tablename where columnName = 'xx' .
b. 统计精度要求精准的话,由于存在各类场景的查询,innodb 引擎不适合去做这类聚合统计查询的业务,冗余一张 myisam 引擎的表去查询或者更换数据库

2.分页语句,limit 偏移量越大,查询愈慢,可以使用唯一索引做偏移量查询,常见的就是自增 id ,示例
SELECT id FROM tablename WHERE id > 10000 order by id desc limit 10.
me1onsoda
340 天前
游标?
encro
340 天前
我们就是默认只差最近 3 天的,时间建立一个索引。
catamaran
340 天前
列数据库性能是真的快,比如 clickhouse ,但是对于数据的修改很不友好,不知道 oceanbase 怎么样,正在了解中。
Features
340 天前
@ShuA1 用 explain 确实快很多,但是返回的 rows 应该是有问题的
我这里测试,mysql5.7 ,设置 WHERE 条件以后,这个 rows 最大只能到 52618055
不知道是索引问题还是什么情况
Pastsong
340 天前
用 cursor

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1008741

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX