天天看點

mysql表分區多表連結查詢_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;

mysql表分區多表連結查詢_MySql分區後建立索引加速單表查詢和連表查詢

我們對訂單表進行查詢的時候,發現雖然僅僅掃描‘p2’分區,但是沒有使用到主鍵索引,有點遺憾。

同樣,我們也對訂單商品表進行查詢分析:

EXPLAIN PARTITIONS SELECT * FROM `zstb_orders_goods` WHERE org_id = 150;

mysql表分區多表連結查詢_MySql分區後建立索引加速單表查詢和連表查詢

結果還是隻掃描'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;

mysql表分區多表連結查詢_MySql分區後建立索引加速單表查詢和連表查詢

對主表‘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`);

mysql表分區多表連結查詢_MySql分區後建立索引加速單表查詢和連表查詢

建立完之後,我們先看看單表查詢情況:

EXPLAIN PARTITIONS SELECT * FROM `zstb_orders_goods` WHERE org_id = 150;

mysql表分區多表連結查詢_MySql分區後建立索引加速單表查詢和連表查詢

剛才雖然掃描了'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;

mysql表分區多表連結查詢_MySql分區後建立索引加速單表查詢和連表查詢

即掃描了分區表,又使用到了索引!

當然,如果希望主表'zstb_orders'查詢的時候也使用索引的話,那麼我們也需要對'zstb_orders'建立'org_id'索引即可。

————————————————

版權聲明:本文為CSDN部落客「咆哮的程式猿」的原創文章,遵循 CC 4.0 BY-SA 版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/konkon2012/article/details/96482548