MySql分区后创建索引加速单表查询和连表查询
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/konkon2012/article/details/96482548
为了加快查询,我们通常根据Where条件创建索引!那么分区后再创建索引,那就应该更快了!
我们依据订单表和订单商品表举例,先创建表结构:
CREATE TABLE `zstb_orders` (
`order_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`org_id` INT(10) UNSIGNED NOT NULL,
`order_money` DECIMAL(6,2) UNSIGNED NOT NULL DEFAULT '0.00',
PRIMARY KEY (`order_id`,`org_id`),
KEY `order_id` (`order_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
CREATE TABLE `zstb_orders_goods` (
`order_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`org_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`goods_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`goods_name` VARCHAR(20) DEFAULT '',
PRIMARY KEY (`order_id`,`org_id`,`goods_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
我们通过`org_id`来对两张表进行分区,脚本如下:
ALTER TABLE `zstb_orders` PARTITION BY RANGE(`org_id`) (
PARTITION p1 VALUES LESS THAN (100),
PARTITION p2 VALUES LESS THAN (200),
PARTITION p3 VALUES LESS THAN (300),
PARTITION p4 VALUES LESS THAN (400),
PARTITION p5 VALUES LESS THAN MAXVALUE
);
ALTER TABLE `zstb_orders_goods` PARTITION BY RANGE(`org_id`) (
PARTITION p1 VALUES LESS THAN (100),
PARTITION p2 VALUES LESS THAN (200),
PARTITION p3 VALUES LESS THAN (300),
PARTITION p4 VALUES LESS THAN (400),
PARTITION p5 VALUES LESS THAN MAXVALUE
);
至于为什么要使用'org_id'来进行分区,不是本文要讨论的问题,你可以根据你自身的需求使用其他字段来进行分区。
然后插入几条数据:
INSERT INTO `zstb_orders`(`order_id`, `org_id`, order_money) VALUES (1, 50, 200);
INSERT INTO `zstb_orders_goods`(`order_id`,`org_id`,`goods_id`,`goods_name`) VALUES (1, 50, 1, '酸奶');
INSERT INTO `zstb_orders_goods`(`order_id`,`org_id`,`goods_id`,`goods_name`) VALUES (1, 50, 2, '纯奶'); INSERT INTO `zstb_orders`(`order_id`, `org_id`, order_money) VALUES (2, 150, 200);
INSERT INTO `zstb_orders_goods`(`order_id`,`org_id`,`goods_id`,`goods_name`) VALUES (2, 150, 1, '酸奶');
INSERT INTO `zstb_orders_goods`(`order_id`,`org_id`,`goods_id`,`goods_name`) VALUES (2, 150, 2, '纯奶'); INSERT INTO `zstb_orders`(`order_id`, `org_id`, order_money) VALUES (3, 350, 200);
INSERT INTO `zstb_orders_goods`(`order_id`,`org_id`,`goods_id`,`goods_name`) VALUES (3, 350, 1, '酸奶');
INSERT INTO `zstb_orders_goods`(`order_id`,`org_id`,`goods_id`,`goods_name`) VALUES (3, 350, 2, '纯奶');
接下来我们来进行查询分析:
EXPLAIN PARTITIONS SELECT * FROM `zstb_orders` WHERE org_id = 150;

我们对订单表进行查询的时候,发现虽然仅仅扫描‘p2’分区,但是没有使用到主键索引,有点遗憾。
同样,我们也对订单商品表进行查询分析:
EXPLAIN PARTITIONS SELECT * FROM `zstb_orders_goods` WHERE org_id = 150;

结果还是只扫描'p2'分区,并没有使用到主键索引。
我们再分析连表查询试试:
EXPLAIN PARTITIONS SELECT * FROM `zstb_orders` AS o JOIN `zstb_orders_goods` AS g ON o.order_id = g.order_id WHERE o.org_id = 150;

对主表‘zstb_orders’的查询虽然只扫描‘p2’分区,但是没有使用主键索引。
对连表‘zstb_orders_goods’的查询是扫描全表,但是使用了主键索引,为什么没有扫描具体的分区表呢?
EXPLAIN PARTITIONS SELECT * FROM `zstb_orders` AS o JOIN `zstb_orders_goods` AS g ON o.order_id = g.order_id AND o.org_id = g.org_id WHERE o.org_id = 150;
考虑‘zstb_orders_goods’是通过'org_id'进行分区的,但是连表查询的时候,没有指明对'org_id',我们只需要在关联查询条件
上面增加‘org_id’的关联即可,分析如下:
主表查询没有变化,连表‘zstb_orders_goods’的查询虽然找到了分区表'p2',但是索引又丢失了!
所以,如果我们需要建立分区的同时,还要使用索引的话,得重新创建了。
ALTER TABLE `zstb_orders_goods` ADD INDEX org_id_index(`org_id`);

创建完之后,我们先看看单表查询情况:
EXPLAIN PARTITIONS SELECT * FROM `zstb_orders_goods` WHERE org_id = 150;

刚才虽然扫描了'p2'分区,但是没有使用索引,这次我们创建索引后,它就用上了,OK!
在分析刚才的连表查询语句:
EXPLAIN PARTITIONS SELECT * FROM `zstb_orders` AS o JOIN `zstb_orders_goods` AS g ON o.order_id = g.order_id AND o.org_id = g.org_id WHERE o.org_id = 150;

即扫描了分区表,又使用到了索引!
当然,如果希望主表'zstb_orders'查询的时候也使用索引的话,那么我们也需要对'zstb_orders'创建'org_id'索引即可。
————————————————
版权声明:本文为CSDN博主「咆哮的程序猿」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/konkon2012/article/details/96482548
MySql分区后创建索引加速单表查询和连表查询的更多相关文章
- Oracle常用操作——创建表空间、临时表空间、创建表分区、创建索引、锁表处理
摘要:Oracle数据库的库表常用操作:创建与添加表空间.临时表空间.创建表分区.创建索引.锁表处理 1.表空间 ■ 详细查看表空间使用状况,包括总大小,使用空间,使用率,剩余空间 --详细查看表空 ...
- 几百万的数据,mysql快速高效创建索引
有一个问题,一张表有3百万条记录,随着时间的增加,记录量会更多,此时查询速度很慢.在创建此表前没有未相应字段添加索引,所以此时需要为表添加索引.但是因为数据量大的原因,索引添加不成功,想了很多办法,终 ...
- mysql 分区后查询效率
准备工作: 蠕虫复制 文章表 增加数据到112万 语法:insert into tableNameA select * from tableNameB 未分区查询 54s 改变现有表 ...
- MySQL 分区建索引
200 ? "200px" : this.width)!important;} --> 介绍 mysql分区后每个分区成了独立的文件,虽然从逻辑上还是一张表其实已经分成了多张 ...
- mysql分区表之三:MySQL分区建索引[转]
介绍 mysql分区后每个分区成了独立的文件,虽然从逻辑上还是一张表其实已经分成了多张独立的表,从“information_schema.INNODB_SYS_TABLES”系统表可以看到每个分区都存 ...
- mysql笔记02 创建高性能的索引
创建高性能的索引 1. 索引(在MySQL中也叫做"键(key)")是存储引擎用于快速找到记录的一种数据结构. 2. 索引可以包含一个或多个列的值.如果索引包含多个列,那么列的顺序 ...
- SOLR对多个(关联)表创建索引
又两天没写博客,关于SOLR的东西,写了一周了还没写完我也是醉了,毕竟会的东西真不多,周四晚上加班没写,周五晚上公司同事聚会也没写,今天在家,还是把最后的一点写完吧,我会的剩下的也就是一个对多个表创建 ...
- MySQL的视图和索引
MySQL的视图 简单来说MySQL的视图就是对SELECT 命令的定义的一个快捷键,我们查询时会用到非常复杂的SELECT语句,而这个语句我们以后还会经常用到,我们可以经这个语句生产视图.视图是一个 ...
- MySQL数据库篇之索引原理与慢查询优化之一
主要内容: 一.索引的介绍 二.索引的原理 三.索引的数据结构 四.聚集索引与辅助索引 五.MySQL索引管理 六.测试索引 七.正确使用索引 八.联合索引与覆盖索引 九.查询优化神器--explai ...
随机推荐
- python系列:二、Urllib库的高级用法
1.设置Headers 有些网站不会同意程序直接用上面的方式进行访问,如果识别有问题,那么站点根本不会响应,所以为了完全模拟浏览器的工作,我们需要设置一些Headers 的属性. 打开我们的浏览器,调 ...
- 申请软件著作权,wps显示代码行号功能
申请软件著作权时,要提交代码. 格式要求,每页不少于50行,怎么设置格式,保障每页至少50行呢? 选择[页面布局]---[行号]--[每页重编行号]即可显示出来,根据显示出来的行号,调整行距等格式即可 ...
- Class.getDeclaredFields()和Class.getFields()的区别。 Class.getMethods()和Class.getDeclaredMethods()的区别。
package www.cn.extend; /** Animal * 2019/07/04 * @author Administrator * */ public class Animal { pu ...
- 自动化运维-ansible入门篇
1.ansible配置 什么是Ansible IT自动化工具 依赖于现有的操作系统凭证来访问控制远程机器 简单易用.安全可靠 Ansible可以完成哪些任务 配置系统 开发软件 编排高级的IT任务 A ...
- centos安装zookeeper,并集群配置
所有机器操作都一样! 注:zookeeper配置集群时 需把防火墙关掉 或者暴露配置文件里配置的端口, 并且在dataDir目录下要有myid文件 1 下载 wget https://mirrors. ...
- Go - IDE的选择与GoLand的安装
目录 常用编辑器的选择 IDE的选择 GoLand的下载与安装 下载 安装 常用编辑器的选择 编写go程序,可以选择的编辑软件有很多,其中包括: notepad++ sublime visual st ...
- python 打印html源码中xpath
实例: #coding:utf-8 from lxml import etree import urllib url=urllib.urlopen('http://www.baidu.com').re ...
- [USACO08OCT]:打井Watering Hole(MST)
题意:有N个牧场,每个牧场修水井花费Wi,连接牧场花费Pij,问最小花费,使得每个牧场要么有水井,要么和有水井的牧场有通道. 思路:加一个格外的节点O,连接O表示修井,边权是修井的费用. 那么 ...
- dimensionality reduction动机---visualization(将数据可视化帮助我们更好地理解数据)
如果我们能更好地理解我们的数据,这样会对我们开发高效的机器学习算法有作用,将数据可视化(将数据画出来能更好地理解数据)出来将会对我们理解我们的数据起到很大的帮助. 高维数据如何进行显示 GDP: gr ...
- js遍历localStorage的键值对
//遍历本地存储localStorage for (var i = 0; i < localStorage.length; i++) { var key = localStorage.key(i ...