SQL SELECT 如何处理大数据量查询?

说实话,我还是第一次遇到这种贯穿整个棋盘的询问,着实心痛不已。
我记得在某个电商项目中有一个报表要求。
从订单中选择日期 = '2 02 3 -1 2 -2 5 '。
那一刻,服务器的CPU飙升到了2 00%,后端经理急得满头大汗,因为机器只有4 核8 GB,根本应付不了。

你看,这就是一个不懂优化的典型例子。
该表可以包含数十万行,即使每行只有几百字节长,扫描它们也将占用大量资源。
后来我们改成 SELECT order_id,total_amount FROM Orders WHERE date = '2 02 3 -1 2 -2 5 ',并添加索引,秒级出结果。
这就是限制返回字段的力量,特别是对于TEXT和BLOB字段,它们可能只占行数的1 %,但却占用了巨大的空间。

有趣的是分页查询点。
我以前在银行系统中见过更夸张的,用LIMIT 1 000 OFFSET 5 0000。
想想看,你得先找到第5 0000条记录。
您应该扫描多少行?后来改为WHERE transaction_id > 'some_id',直接定向到目标位置。
效率的提升也不小。
就好像你找书的时候,不用一页一页地翻,直接翻到目录中相应的页即可。

我在创建索引时遇到了困难。
我曾经使用YEAR(列)执行查询,但结果根本无法执行。
后来发现该列没有索引,数据库必须重新计算每一行的年份。
直接改写为范围查询后,响应时间从1 小时缩短到1 0秒。
这让我意识到索引不是随机建立的,它取决于实际的查询模式。

我特别推荐分区表。
我们有一个按天分区的日志系统。
以前,要查看某个月的数据,必须扫描整个表。
现在可以直接 WHERE log_date BETWEEN '2 02 3 -03 -01 ' AND '2 02 3 -03 -3 1 ',解析的行数直接减少了 9 0%。
但需要注意的是,分区并不是万能的,要看业务场景。
例如,MySQL的RANGE分区对于时态查询非常友好,但HASH分区更加统一,适合随机搜索。
异步后台处理也是一个技巧。
以前,你需要一份营销报告,客户坚持要实时出结果,但结果一执行就填满了内存。
后来转变为计划任务。
计算是一大早进行的,并记录在汇总表中,白天直接查看预算结果。
客户满意度实际上更高,因为报告的质量没有改变并且系统仍然稳定。

我通常谨慎使用采样,但它确实有效。
有一个分析场景,用户只关心大趋势,比如“今天的销量是3 0%”。
比昨天高”,而且没必要对每个订单都精确。
使用TABLESAMPLE SYSTEM(1 0)提供了一个快速的答案,但你必须接受结果可能不是绝对准确的。
就像你买东西时,包装盒照片看起来不错,但打开时实际颜色可能会有所不同。

说实话,这些方法单独使用时效果有限,但组合起来就很强大。
例如分页查询+分区表+有限字段,这种组合可以我最近给一个客户端处理大规模数据查询的时候,要等十分钟,现在两秒就出结果了,
数据量大,SQL优化就像在高速公路上开车,你想想,全表扫描,1 %和9 9 %的CPU差距是巨大的,但关键还是看具体的表结构、索引、数据分布,我没有亲自管理过这方面的所有数据库,MySQL和PostgreSQL的优化思路可能略有不同,但基本原理是一样的。

大数据量多列求和查询如何优化?

缓存求和值+增量逻辑,结果存储在Redis中,更新频率为5 分钟。
这是一个陷阱。
不要相信固定频率。
业务变化会导致延误。
不要那样做。

如何处理SQL查询中的重复数据?通过去重和索引优化查询效率

直接使用DISTINCT。
对于大量数据使用 GROUP BY。
对于复杂的规则,请使用 ROW_NUMBER()。
创建复合索引。
WHERE 和 JOIN 列也必须建立索引。
不要忘记过滤数据大小。