zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    分工的好处
    这是真正的随笔,无论形式还是内容。。。
    javascript 检查函数传入的实参个数和期待的形参个数是否相同的方法
    JS中比较难记的函数
    3.0 Basic Usage of Class
    0.0 Visual Studio
    2.0 Exercise of Basic Statements
    5.0 String And RegularExpressions.
    1.0 HelloWorld
    dell mini9 fluxbox 声卡的安装 和 屏幕分辨率和刷新率的调节
  • 原文地址:https://www.cnblogs.com/sandea/p/11776145.html
Copyright © 2011-2022 走看看