第41期:MySQL 哈希分区表

Mysql如何创建Hash索引 MySQL创建Hash索引 以下是武汉理工大学数据库综合实验的一小部分 最近在写数据库实验,现在进行到索引部分,下面内容记录了学习过程中需要的一些知识,本次笔记主要记录如何创建Hash索引 题目如下: 创建一个包含(employeeID, name, education)等字段的临时员工表 (tmpEmployee) ,并在该表的员工编号字段上创建一个HASH索引 代码如下: 创建表 mysql&... 阅读详情

提到分区表,一般按照范围(range)来对数据拆分居多,以哈希来对数据拆分的场景相来说有一定局限性,不具备标准化。接下来我用几个示例来讲讲 MySQL 哈希分区表的使用场景以及相关改造点。

对于哈希分区表,最通俗的方法就是 hash 单个字段,比如下面表 hash_t1(存有500W行记录),按照自增 ID 来做 HASH ,分区数目为 1024 :

mysql:ytt_new> show create table hash_t1\G
*************************** 1. row ***************************
       Table: hash_t1
Create Table: CREATE TABLE `hash_t1` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `r1` int DEFAULT NULL,
  `log_date` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
/*!50100 PARTITION BY HASH (`id`)
PARTITIONS 1024 */
1 row in set (0.00 sec)

mysql:ytt_new> select count(*) from hash_t1;
+----------+
| count(*) |
+----------+
|  5000000 |
+----------+
1 row in set (2.43 sec)

表 hash_t1 的分区方式很好理解,按照 ID 来对数据进行 HASH 拆分,也就是按照分区数量求模, 类似于 hash(mod(id,1024)) ,数据分布非常均匀。

mysql:ytt_new> select max(table_rows),min(table_rows) from information_schema.partitions where table_name = 'hash_t1';
+-----------------+-----------------+
| max(table_rows) | min(table_rows) |
+-----------------+-----------------+
|            4883 |            4882 |
+-----------------+-----------------+
1 row in set (0.04 sec)

接下来考虑以下几条 SQL 语句:

SQL 1:select count(*) from hash_t1 where id = 1;

SQL 2:select count(*) from hash_t1 where id in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);

SQL 3:select count(*) from hash_t1 where  id <=1;

SQL 4:select count(*) from hash_t1 where id <=15;

SQL 1 和 SQL 2 非常适合检索哈希分区表,SQL 3 和 SQL 4 就不太适合。

SQL 1 的执行计划:对于哈希分区表来说为最优场景,能具体到某单个分区,过滤值为常量。

mysql:ytt_new> explain select count(*) from hash_t1 where id = 8\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: hash_t1
   partitions: p8
         type: const
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: const
         rows: 1
     filtered: 100.00
        Extra: Using index
1 row in set, 1 warning (0.00 sec)

SQL 2 针对字段 ID 的过滤条件为15个常量组合,具体到15个分区,对比总分区数来讲比例很小,也很优化。不过从执行计划来看,还有优化空间,可以考虑改变分区表的哈希方式,后面介绍。

SQL 2 的执行计划:

mysql:ytt_new> explain select count(*) from hash_t1 where id  in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: hash_t1
   partitions: p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15
         type: range
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: NULL
         rows: 15
     filtered: 100.00
        Extra: Using where; Using index
1 row in set, 1 warning (0.00 sec)

SQL 3 、SQL 4 与 SQL 1 、SQL 2 实现的效果一样,不过却要扫描所有分区才能拿到结果。

来同样看下 SQL 3 执行计划:

mysql:ytt_new> explain select count(*) from hash_t1 where  id <=1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: hash_t1
   partitions: p0,p1,p2,...,p1021,p1022,p1023
...

所以需要注意的是哈希分区表仅限于等值过滤检索,类似对普通表基于哈希索引的检索。

之前我们有看到 SQL 2 扫描了不必要的分区, 那能否减少 SQL 2 扫描的分区数量呢?答案是可以的。

得重新对表数据进行哈希拆分,由需求到定义反着来:

创建一张新表 hash_t2 , 按照 Id div 1024 来分区,每个分区就能严格按照 ID 顺序存放前 1024 个值:

mysql:ytt_new> create table hash_t2 (id bigint unsigned auto_increment primary key, r1 int, log_date date) partition by hash(id div 1024) partitions 1024;
Query OK, 0 rows affected (10.54 sec)

mysql:ytt_new>load data infile '/var/lib/mysql-files/hash_sample.csv' into table hash_t2;
Query OK, 5000000 rows affected (3 min 20.11 sec)
Records: 5000000  Deleted: 0  Skipped: 0  Warnings: 0

来看看效果:此时 SQL 2 可以基于单个分区 p0 来检索数据。

mysql:ytt_new> explain select count(*) from hash_t2 where id in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: hash_t2
   partitions: p0
         type: range
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 8
          ref: NULL
         rows: 15
     filtered: 100.00
        Extra: Using where; Using index
1 row in set, 1 warning (0.00 sec)

此外,哈希分区还适合特定的日期类等值查询场景, 分区定义比按照范围要简单,实现效果一样。比如按照日期来检索的 SQL 5 :

SQL 5: select count(*) from hash_t1 where log_date= '2020-08-05';

创建新表 hash_t3 ,分区字段为 year(log_date) :

mysql:ytt_new>create table hash_t3 (id bigint unsigned , r1 int,log_date date, key idx_log_date(log_date));
Query OK, 0 rows affected (0.04 sec)

mysql:ytt_new>alter table hash_t3 partition by hash(year(log_date)) partitions 11;
Query OK, 0 rows affected (0.32 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql:ytt_new>load data infile '/var/lib/mysql-files/hash_sample.csv' into table hash_t3;
Query OK, 5000000 rows affected (2 min 4.59 sec)
Records: 5000000  Deleted: 0  Skipped: 0  Warnings: 0

定义好新表,来看下 SQL 5 的执行计划: 基于日期的检索也能限定在单个分区。


mysql:ytt_new>explain  select count(*) from hash_t3 where log_date = '2020-08-05'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: hash_t3
   partitions: p7
         type: r
possible_keys: idx_log_date
          key: idx_log_date
      key_len: 4
          ref: const
         rows: 1405
     filtered: 100.00
        Extra: Using index
1 row in set, 1 warning (0.00 sec)

这里用 year 还不够优化,后期随着数据量增加,每个分区的数据会有增长,可以考虑按照 month 来拆分数据。

MySQL 还有一个特殊的哈希分区:不限制输入数据类型的KEY 分区,哈希函数预定义为系统函数 PASSWORD ,定义更加简单,适合主键非整型字段的表。

以上这些都只是考虑查询性能,如果后期分区经常扩容,缩容等,可以考虑线性哈希分区。

线性哈希是一致性哈希在 MySQL 里的具体实现,其目的就是为了解决分区表后期扩缩容性能问题。不过会带来分区数据分布不均匀、出现数据热点、相同 SQL 扫描记录数被放大等新问题。

用一个简单例子来对比下两者的差异:把表 hash_t1 分区数量缩减到10个,总花费时间2分钟46秒:

mysql:ytt_new>alter table hash_t1 coalesce partition 1014;
Query OK, 0 rows affected (2 min 46.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

新建线性哈希表 hash_linear_t1 ,初始分区数目也是 1024 ,同样把分区数目减少到10个。 缩减分区的时间为1分钟28秒,比操作表 hash_t1 时间上少了一半左右。

mysql:ytt_new>create table hash_linear_t1 (id bigint unsigned auto_increment primary key, r1 int,log_date date) partition by linear hash(id) partitions 1024;
Query OK, 0 rows affected (34.13 sec)

mysql:ytt_new>load data infile '/var/lib/mysql-files/hash_sample.csv' into table hash_linear_t1 ;
Query OK, 5000000 rows affected (2 min 7.78 sec)
Records: 5000000  Deleted: 0  Skipped: 0  Warnings: 0

mysql:ytt_new>alter table hash_linear_t1 coalesce partition 1014;
Query OK, 0 rows affected (1 min 28.29 sec)
Records: 0  Duplicates: 0  Warnings: 0

来看下两张分区表的数据分布情况:很明显,线性哈希表数据分布不是很均匀,存在严重的数据热点问题。

mysql:ytt_new>select table_rows from information_schema.partitions where table_name = 'hash_t1';
+------------+
| TABLE_ROWS |
+------------+
|     485723 |
|     537704 |
|     523017 |
|     470724 |
|     478982 |
|     512272 |
|     483190 |
|     455829 |
|     520512 |
|     461572 |
+------------+
10 rows in set (0.00 sec)

mysql:ytt_new>select table_rows from information_schema.partitions where table_name = 'hash_linear_t1 ';
+------------+
| TABLE_ROWS |
+------------+
|     269443 |
|     340989 |
|     611739 |
|     584321 |
|     566181 |
|     624040 |
|     637801 |
|     688467 |
|     331397 |
|     317695 |
+------------+
10 rows in set (0.01 sec)

本篇介绍了 MySQL 哈希分区表的使用场景以及一些细微差异。切记:哈希分区不能用于范围查询,只能用作等值查询场景。


关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!

【GaussDB(DWS)】数据分布式存储——hash分区表数据分布方式 水平分表方式将一个数据表内的数据,按合适分布策略分散存储在多个节点内,DWS支持如表1所示的数据分布策略。用户可在CREATE TABLE时指定DISTRIBUTE BY参数进行分片,指定PARTITION BY对分片进行一步分区,以此来组织数据的分布方式。DWS采用水平分表的方式,将业务数据表的元组打散存储到各个节点内。这样带来的好处在于,查询中通过查询条件过滤不必要的数据,快速定位到数据存储位置,可极大提升数据库性能。 阅读详情

相关推荐

【DM】达梦数据库中分区表的创建及查询操作

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取! | | >=10&&=100&&=1000 |建表CREATE TABLE HA.INFO(NAME VARCHAR(50),PRICE INT)PARTITION BY RANGE(PRICE)(PARTITION P1 VALUES LESS THAN (10),PARTITION P2 VALUES LESS THAN (100),PARTITION

m0_75232472的博客 1135

Mysql分区 - Hash分区

Hash(哈希) – 这种模式允许DBA通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。例如DBA可以建立一个对表主键进行分区的表。

秃头的博客 5871

基于PWM的汽车仪表步进电机微步驱动优化实践

本文深入探讨了基于PWM的微步驱动技术,用于优化汽车仪表步进电机的运行性能。通过将传统的分步驱动升级为PWM微步细分驱动,利用正弦/余弦查表法合成旋转磁场,有效消除了指针抖动与噪声,实现了指针的平滑、精准运动。文章以STM32和VID2905电机为例,提供了详细的硬件连接、代码实现及高级优化技巧,为提升汽车仪表体验提供了实用方案。

weixin_29169505的博客 510

mysql实现hash分表

mysql作为站点后端的重要数据落地组成部分,可谓是运用相当之广泛。在web应用中,往往庞大的数据会最终落地到mysql中,当一张mysql单表记录了上10亿的记录时,性能往往不会很理想,于是我们往往会将一张单表拆分成多张相同的分表。今天我们主要来讲如何合理的进行分表。 1、对一个字段进行分表: 这种分表方式,是我在工作中直接应用到的一种方式: 举一个简单的例子: 比如电商网站,需要记录用

dengjiexian123的专栏 2万+

别再手动改文献了!手把手教你定制Mendeley的GB/T 7714-2005引用格式(附常见问题修复)

本文详细指导如何定制Mendeley的GB/T 7714-2005引用格式,解决科研文献管理中的常见问题。通过深度解析Mendeley样式编辑器,精准控制作者显示规则、出版社信息精简及期刊页码处理,实现参考文献一键合规。附常见问题修复和实战调试方法,大幅提升学术写作效率。

weixin_26833503的博客 374

ARM CoreSight架构

CoreSight架构是现代复杂SoC的“飞行数据记录仪”(黑匣子)和“精密诊断仪”的结合体。它彻底改变了嵌入式系统的调试方式,从传统的“盲人摸象”变成了拥有“上帝视角”,是ARM生态系统能够支撑起从微控制器到高性能服务器芯片如此广泛产品线的重要基石技术之一。

guigenyi的专栏 1421

MySQL的哈希分区分区表

概念、使用方法和优势

weixin_72431427的博客 938

大数据审计常用的算法模型

数据预处理:用聚类算法(K-Means)对数据分组,缩小分析范围;异常初筛:用孤立森林/DBSCAN快速标记疑似异常样本;风险分级:用随机森林/XGBoost对疑似异常打分,确定核查优先级;关联深挖:用FP-Growth挖掘异常样本背后的人员/流程关联;文本佐证:用BERT分析相关合同/审批文本,获取舞弊证据。例如,某审计项目通过“K-Means分组→孤立森林标异常→FP-Growth找关联→BERT审合同”的流程,仅用1周就完成了过去3个月需10人团队的工作量,且挖出2起隐藏的串标舞弊案。

Yulay专栏 1066

MySQL分区表详解

通常情况下,同一张表的数据在物理层面都是存放在一起的。随着业务增长,当同一张表的数据量过大时,会带来管理上的不便。而分区特性可以将一张表从物理层面根据一定的规则将数据划分为多个分区,多个分区可以单独管理,甚至存放在不同的磁盘/文件系统上,提升效率。 分区表的优点: 数据可以跨磁盘/文件系统存储,适合存储大量数据。 数据的管理非常方便,以分区为单位操作数据,不会影响其他分区的正常运行。 数据查询上在某些条件可以利用分区裁剪(partition pruning)特性,将搜索范围快速定位到特性分区,提升查

最简单的方法,解决最实际的问题。 2万+

保姆级教程:用Verilog手把手实现一个MIPI CSI-2 D-PHY接收器(附PPI接口时序详解)

本文提供了一份详细的Verilog实现MIPI CSI-2 D-PHY接收器的教程,重点解析了PPI接口时序和deskew数据对齐技术。通过模块划分、时钟域处理、状态机设计和错误恢复机制等实战内容,帮助开发者掌握高速数据接收的核心技术,适用于嵌入式视觉系统开发。

weixin_30619101的博客 512

[密码学实战]密评考试训练系统v1.0程序及密评参考题库(获取路径在文末)(二十四)

本系统将密码学理论与软件工程实践相结合,为密评备考提供了高效解决方案。随着《密码法》的深入实施,掌握密评知识将成为信息安全从业者的核心竞争力。立即开始您的密码安全专家之旅!(注:实际应用请以最新发布版本为准)

曼岛_的博客 796

MySQL 8.0 表分区

mysql8.0,分区

nannanstyle的博客 4908

【漏洞复现】CVE-2024-44902 Thinkphp反序列化漏洞

Thinkphp v6.1.3至v8.0.4版本中存在反序列化漏洞,攻击者可利用此漏洞执行任意代码。

渗透之路,攻防之间皆学问 6705

Mysql分区表------范围分区表(新增、删除、重组、查看)

当我们删除p1分区以后,p1分区原来的分区区间定义将由他后面的分区定义区间所继承。而且数据将会被删除。– 查询p0和p1分区。根据以上命令可以查询分区的相关数据库信息。表的分区结构中新建的4个分区已新建。由此可见4个分区文件生成。

睡不醒的每天 6438

ADBC 全面解析:ABAP 开发者玩转 Native SQL 的实战指南

本文介绍了 SAP ABAP 中的 ADBC(ABAP Database Connectivity)技术,它是一种基于 ABAP 面向对象的类库,用于访问 Native SQL 接口。与 Open SQL 和 EXEC SQL 相比,ADBC 具有以下优势:支持特定数据库语法、可访问二级数据库连接、执行多种 SQL 操作且语法更 ABAP 化。文章通过示例展示了 ADBC 的基本用法,包括创建语句对象、执行查询和处理结果集。建议在需要数据库特有功能或二级连接时优先使用 ADBC,同时提供封装类来简化调用。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 306

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

MYSQL分区

一、什么是数据库分区 mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的datadir来查看),一张表主要对应着三个文件,一个是frm存放表结构的,一个是myd存放表数据的,一个是myi存表索引的。如果一张表的数据量太大的话,那么myd,myi就会变的很大,查找数据就会变的很...

weixin_33892359的博客 151

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

mysql的分区

在mysql 5.1.3之后引入和partition(分区)的概念。这个是个好东东。以前遇到一个大表的时候,我们会手动将其分为几个小表(就是分表操作)。但是分表操作有几个缺点:1 麻烦,这里指的麻烦是不仅对于调用分表的sql语句的处理上,也是分表的具体操作步骤上。2 当一个表从单表变为分表的时候,上层sql逻辑也需要进行修改,而且是大范围的修改!   引入分区的概念就简单多了。强调一点

binyao02123202的专栏 928

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

MySQL分区

一张表的数据在物理层面都是存放在一起的。随着业务增长,当一张表的数据量过大时,会带来不便。而分区可以将一张表从物理层面根据一定的规则将数据划分为多个分区,分区可以单独管理,存放在不同的磁盘,提升效率。

小史史啊 561

MySQL 分区

1:分区概述 分区的过程是将一个表或索引分解为多个更小、更可管理的部分。就访问数据库的应用而言,逻辑上只有一个表或者索引,物理上可能由是个物理分区组成。每个分区都是独立的对象,可独自处理,也可以作为一个更大的部分进行处理。 查看MySQL是否支持分区: mysql&gt; SHOW VARIABLES LIKE '%partition%'\G *********************...

weixin_33810302的博客 67

MySQL中的分区表

MySQL分区技术摘要 MySQL分区技术将大表数据按规则划分为多个物理分区,提升管理效率和查询性能。主要分区类型包括: 范围分区(Range):按连续值范围划分,适合时间序列数据 列表分区(List):按离散值列表划分 哈希分区(Hash):均匀分布数据 键值分区(Key):基于主键/唯一键自动分区 每种分区类型支持变种(如Range Columns/List Columns)和复合分区(子分区)。分区管理操作包括: 新增/删除分区 重组分区数据 分区维护(重建/检查/优化) 分区优势: 跨磁盘存储大规模

Eucalyptus's blog 757

mysql 删除hash分区_MySQL-如何删除hash表分区

一个大表,之前是以hash分区表的形式存在的,MySQL> show create table history_uint;| history_uint | CREATE TABLE `history_uint` (`itemid` bigint(20) unsigned NOT NULL,`clock` int(11) NOT NULL DEFAULT ‘0‘,`value` bigint(...

weixin_35123329的博客 283

mysql分表分区

分布式查询: 今天分布式查询出现以下错误: Caused by: java.sql.SQLException: UDAL - DBProxy internal error: invalid route in sql, multi tables found but datanode has no intersection sql:select pomi.offer_obj_inst_rel_id

LuuvyJune的博客 7959
上一篇: 故障分析 | 手动 rm 掉 binlog 导致主从报错
下一篇: 故障分析 | MySQL 5.7 使用临时表导致数据库 Crash
爱可生开源社区
博客等级 码龄8年 1936粉丝 1004原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值