早期工作中没有做好足够的设计,目前记录表单表数据2000w且无有效索引,表现是分页缓慢,模糊查询拉闸。

当前业务中,写操作会多于读操作,时不时会遇到慢SQL占用过多的数据连接,导致写操作无法正常进行。作为记录表有着明显的冷热数据,综合考虑下使用数据分区表解决读操作过慢的问题

下面是问题解决记录:

1 分离热点数据

对记录表进行分区,缩小数据筛选范围

这里我选用的时间字段 create_time[TIMESTAMP]

ALTER TABLE record PARTITION by RANGE(UNIX_TIMESTAMP(create_time))
(
PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-01-01 00:00:00') ),
PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-02-01 00:00:00') ),
PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-03-01 00:00:00') ),
PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-04-01 00:00:00') ),
PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-05-01 00:00:00') ),
PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-06-01 00:00:00') ),
PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-07-01 00:00:00') ),
PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-08-01 00:00:00') ),
PARTITION p9 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-09-01 00:00:00') ),
PARTITION p10 VALUES LESS THAN (UNIX_TIMESTAMP('2020-10-01 00:00:00') )
)

这里有几个常见的错误

  • A PRIMARY KEY must include all columns in the table's partitioning function
  • A UNIQUE INDEX must include all columns in the table's partitioning function

意思是表上的每一个唯一索引都必须位于分区表的表达式上,如果我选用create_time作为分区字段,那么这个字段就必须是唯一索引。【PRIMARY KEY或者 UNIQUE INDEX】

所以删除原有的PRIMARY KEY【主键id】建立联合主键

ALTER TABLE record DROP PRIMARY KEY, ADD PRIMARY KEY(id,create_time);

使用下面命令查看各分区记录数量

SELECT PARTITION_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'record';

分析SQL判断查询是否区分分区

EXPLAIN PARTITIONS SELECT id,create_time FROM table_name WHERE create_time> '2020-03-01 00:00:00' AND create_time< NOW()

查询可以区分分区,不再全表查询,优化的初步目的达到。

2 优化查询效率

业务中涉及分页操作,最常见的分页语法中包括2条SQL

  • 获取记录总数 SELECT COUNT(*)
  • 对记录进行分页 SELECT * FROM table_name WHERE xxxxxxx LIMIT n , m

使用分区表后,仅仅是减少了数据筛选范围【2000w数据表只使用最近2月的分区,数据量降低为300w内】,查询效率提升了70%【45s -> 15s】查询耗时还在10s以上并没有完全解决问题

2.1 选择合适的存储引擎

在InnoDB存储引擎下,随着表数据的增大 COUNT(*)和LIMIT 都会变得极其耗时。

MYISAM引擎倒是非常快,但是该引擎并不支持行级锁,读操作是共享锁,写操作是排他锁,支持并发插入,写压力过大情况下可能会遇到表锁情况,长期处于Locked状态。

综合考虑下使用InnoDB

2.2 SQL和业务调整

在业务上做了一定的取舍,去掉了分页的最后一页和输入自定义页码操作,只留下了上下翻页和最近几页跳页面。【参考58同城页面】

这个有些类似ES中的游标查询【scroll】,前后端配合完成,一页一页的查询,每次需要知道当前的有游标也就是主键ID,上页下页和PageSize

SELECT * FROM table_name WHERE id > scroll and id < scroll + pageSize

还见过另一种SQL优化方案,只需要后端即可完成,效率相对低一些 存在limit过大的问题

SELECT * FROM table_name where id >= (SELECT id FROM table_name LIMIT (pageNo-1) * pageSize, 1) LIMIT pageSize

2.3 索引的调整

分区表每一个分区都索引独立存储,记录表涉及到查询,对查询的字段建立索引

增加记录名索引:CREATE INDEX index_name ON table_name(table_field)

最终的查询SQL: SELECT id,name,create_time FROM table_name WHERE table_field like 'xxxx%'AND create_time > '2020-03-01 00:00:00' AND create_time < NOW()

分析SQL:使用Explain ,发现命中索引 查询和分页耗时在0.01-0.04之间,基本满足要求。

以上是使用分区表对大数据库表进行的优化,也存在一些业务上的妥协和局限,比如为了查询命中索引like必须从前到后匹配查询,分页不能跳到指定页面。

若想不在业务上做妥协,可以采取ES来做分页,数据库做基础查询,又或者使用Sphinx来做全文搜索。

业务开发的复杂度,数据的精确程度,以及时效性,三者通常来说指只能满足其二。在不同业务情况下,做不同的取舍,就仁者见仁智者见智了。

使用Mysql分区表对数据库进行优化的更多相关文章

  1. MySQL系列(三)--数据库结构优化

    良好的数据库逻辑设计和物理设计是数据库高性能的基础,所以对于数据库结构优化是很有必要的 数据库结构优化目的: 1.减少数据的冗余 2.尽量避免在数据插入.删除和更新异常 例如:有一张设计不得当的学生选 ...

  2. MySQL 5.7数据库参数优化

    连接相关参数 max_connections:允许客户端并发连接的最大数量,默认值是151,一般将该参数设置为500-2000max_connect_errors:如果客户端尝试连接的错误数量超过这个 ...

  3. MYSQL数据库的优化

    我们究竟应该如何对MySQL数据库进行优化?下面我就从MySQL对硬件的选择.MySQL的安装.my.cnf的优化.MySQL如何进行架构设计及数据切分等方面来说明这个问题. 服务器物理硬件的优化 在 ...

  4. MySql学习(六) —— 数据库优化理论(二) —— 查询优化技术

    逻辑查询优化包括的技术 1)子查询优化  2)视图重写  3)等价谓词重写  4)条件简化  5)外连接消除  6)嵌套连接消除  7)连接消除  8)语义优化 9)非SPJ优化 一.子查询优化 1. ...

  5. MySQL数据库的优化(下)MySQL数据库的高可用架构方案

    MySQL数据库的优化(下)MySQL数据库的高可用架构方案 2011-03-09 08:53 抚琴煮酒 51CTO 字号:T | T 在上一篇MySQL数据库的优化中,我们跟随笔者学习了单机MySQ ...

  6. MySQL数据库的优化(上)单机MySQL数据库的优化

    MySQL数据库的优化(上)单机MySQL数据库的优化 2011-03-08 08:49 抚琴煮酒 51CTO 字号:T | T 公司网站访问量越来越大,导致MySQL的压力越来越大,让我们自然想到的 ...

  7. [转]MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验

    本文转自:http://liangweilinux.blog.51cto.com/8340258/1728131 年,嘿,废话不多说,下面开启MySQL优化之旅! 我们究竟应该如何对MySQL数据库进 ...

  8. mysql数据库性能优化(包括SQL,表结构,索引,缓存)

    优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...

  9. MySQL 数据库性能优化之SQL优化

    前言 有人反馈之前几篇文章过于理论缺少实际操作细节,这篇文章就多一些可操作性的内容吧. 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需要有一些索引知识为基础. 优化目标 ...

随机推荐

  1. Spark基础学习精髓——第一篇

    Spark基础学习精髓 1 Spark与大数据 1.1 大数据基础 1.1.1 大数据特点 存储空间大 数据量大 计算量大 1.1.2 大数据开发通用步骤及其对应的技术 大数据采集->大数据预处 ...

  2. Vue3 + Element ui 后台管理系统

    Vue3 + Element ui  后台管理系统 概述:这是一个用vue3.0和element搭建的后台管理系统界面. 项目git地址: https://github.com/whiskyma/vu ...

  3. Scala集合中的函数(扩展)

    1.拉链(zip) 将两个集合进行 对偶元组合并,可以使用拉链 object Demo_031 { def main(args: Array[String]): Unit = { val list1 ...

  4. Linux 常用软件清单

    Linux 常用软件清单 下面是Linux环境的一些软件(有些只是关键字,直接搜素即可): arch 系列的是 pacman -Ss <关键字> debian 系列的是 apt searc ...

  5. 浅析 MVC

    MVC(Model–View–Controller) Model:数据模型  负责操作所有数据View:视图 负责所有UI界面Controller:控制器 负责其他 //数据放在m const m = ...

  6. Nuxt.js 踩坑记录(2) 使用sequelize时,提示install mysql2,安装了仍然不能解决问题

    打算写一个nuxt.js+sequelize+mysql的个人博客,遇到了挺多坑,还是坚持了下来,终于解决了这个bug. 今天不知道我做了什么,页面就报错了,定位到了使用sequelize的JS文件里 ...

  7. SpringBoot使用简单缓存

    第一步开启缓存(只要是springboot项目就可以)  数据库连接等相关配置请读者自行实现. 在Application启动类上添加注解 @EnableCaching 开启缓存 @SpringBoot ...

  8. java23种设计模式——七、桥接模式

    原文地址:https://www.cnblogs.com/chenssy/p/3317866.html 源码在我的github和gitee中获取 目录 java23种设计模式-- 一.设计模式介绍 j ...

  9. 网站会不会因为同IP网站被K而受到惩罚

    http://www.wocaoseo.com/thread-289-1-1.html 使用虚拟主机的网站会不会因为同一个IP或同一台服务器上有其他网站作弊被处罚而受连累,也被惩罚? 复制代码 百度官 ...

  10. 用python导入20个G的json数据到Mysql数据库

    整体思路参考资料:https://blog.csdn.net/layman2016/article/details/79252499 作业:有一个16个G的跟疫情相关的json新闻大数据(articl ...