开篇语
最近 12306 又崩溃了一次, 但其实 12306 这样的体量跟我们平常接触的架构基本没什么太大的关系.
话又说回来, 12306 也是由一个个小功能组成的.
做好自己的小蚂蚁, 就能让大部队变得更快.
因为跟数据库, 数据仓库, 查询打交道比较多, 所以我就简单说一下数据查询的优化过程吧.
不客气地说, 在性能优化中, 其实 80% 的问题都是源于数据查询.
以下步骤是以优化代价, 数据量级为衡量, 从低到高开始, 步步进推.
GO
(1) 如果数据查询缓慢, 80% 的原因都是因为 SQL. 先找出慢 SQL, 以 Oracle 为例, 可以通过 AWR 报表的方式查看.
(2) 查看慢 SQL 的执行计划, 看看查询的关键字段是不是缺失索引, 添加索引.
(3) 有索引, 但是查看执行计划, 并没有走索引. 此时有两种方法, 一是用 hint, 二是可能数据表最近被大批量的删除, 新增过, 需要手动收集数据表的统计信息, 让 SQL 优化器正常解析 SQL.
(4) 数据表太大, 没有合适的全局索引. 可不可以建设分区表? 按照时间, 地区进行分区操作.
(5) 不能分区, 或者分区效果也不显著, 需要考虑改动表结构了, 有些字段是不是可以拆出去? 做成维表, 扩展表?
[这是垂直拆分. 缺点是查询时如果要查询扩展表字段, 需要 join 操作, 插入修改时要考虑多表, 事物复杂. 单表数据量还是太大.]
(6) 或者可以考虑进行分库分表操作. 对于 Oracle 来说单张 1 亿以下数据分区就够了, 不需要分库分表.
[水平拆分. 缺点是会导致事物一致性更为复杂, 还需引入分库分表的管理中间件.]
(7) 进行历史数据分离. 将一些不常用的数据, 例如两年前的数据都拆分到历史表中.
[即冷热数据分离.]
(8) 读写分离, 再新建个数据查询库, oracle 用 OGG,MySQL 用 binlog 做数据同步, 将查询模块更换数据源.
(9) 增加数据库的服务器性能, 升级硬件, 例如磁盘换上 SSD. 这个方法是被验证过了的, 尤其是查询批量数据, 无高效索引的时候.
(10) 从数据库层面已经无法优化了, 我们可以考虑在应用端使用并行查询的方法爬出数据, 然后再行合并.
[事实上, 很多报表工具都是这么做的.]
(11) 并行查询再高端点, 用流行的话来说, 叫分布式计算.
[12306 就是用 Pivotal 的 GemFire, 将单次查询的最长时间从 15 秒下降到 0.2 秒以下.]
(12) 这个数据库性能就是达到瓶颈了, 我们来更换数据库吧, 换成性能更好的数据库, 要做数据迁移, 重新测试验证, 代价不菲.
(13) 从业务上去优化, 看看这样查询是不是有道理, 这些字段是不是确实需要? 需不需要这么精细? 需不需要这么频繁?
大数据量报表每月一出就行了? 那这样就无所谓时效性了. 嗯, 那我们来做数据仓库吧.
(14) 我们用了 Hadoop + RDBMS 做了数据仓库.
数据仓库不能实时查询怎么办? 我们来做实时仓库吧.
(15) 我们用了 kafka + spark + jstorm 做了实时仓库, 结果你跟我说过时了? 刚刚升级成了 Spark Streaming ? 嗯? 又换成 Flink 了?
好吧, 爱咋咋地.
结语
说到这里没啥可说的了, 或者以后想起来什么还可以再说说吧.
性能优化其实是一个持续迭代的过程, 并非一蹴而就, 也不是一步到位的工作.
有时候有很多方案, 关键是看怎样代价最小.(改造成本, 硬件成本, 紧急状况)
每个人, 还是先从写好一个 SQL, 一段代码开始吧.
撒花, 结束.
END.
来源: https://www.cnblogs.com/yaomaomao/p/12096907.html