MySql分区后建立索引加速单表查询和连表查询

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接和本声明。
本文连接:https://blog.csdn.net/konkon2012/article/details/96482548
为了加快查询,咱们一般根据Where条件建立索引!那么分区后再建立索引,那就应该更快了!.net

咱们依据订单表和订单商品表举例,先建立表结构:blog

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'来进行分区,不是本文要讨论的问题,你能够根据你自身的需求使用其余字段来进行分区。class

而后插入几条数据:bfc

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’分区,可是没有使用到主键索引,有点遗憾。im

一样,咱们也对订单商品表进行查询分析:d3

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

相关文章
相关标签/搜索