MySQL优化之分析查询语句实战演示(一)

129 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情

前言

上篇我们学习了MySQL中的数据库优化之分析查询语句。有兴趣的小伙伴可以阅读(MySQL优化之分析查询语句)。
下面我们继续学习MySQL中的数据库优化之分析查询语句实战演示。

创建模拟数据

创建表s1和s2。

CREATE TABLE s1(
    id INT AUTO_INCREMENT,
    key1 VARCHAR(100),
    key2 INT,
    key3 VARCHAR(100),
    key_part1 VARCHAR(100),
    key_part2 VARCHAR(100),
    key_part3 VARCHAR(100),
    commom_field VARCHAR(100),
    PRIMARY KEY (id),
    INDEX idx_key1 (key1),
    UNIQUE INDEX idx_key2 (key2),
    INDEX idx_key3 (key4),
    INDEX idx_key_part (key_part1, key_part2, key_part3),
) ENGINE = INNODB CHARSET=utf8;
CREATE TABLE s2(
    id INT AUTO_INCREMENT,
    key1 VARCHAR(100),
    key2 INT,
    key3 VARCHAR(100),
    key_part1 VARCHAR(100),
    key_part2 VARCHAR(100),
    key_part3 VARCHAR(100),
    commom_field VARCHAR(100),
    PRIMARY KEY (id),
    INDEX idx_key1 (key1),
    UNIQUE INDEX idx_key2 (key2),
    INDEX idx_key3 (key4),
    INDEX idx_key_part (key_part1, key_part2, key_part3),
) ENGINE = INNODB CHARSET=utf8;

创建函数,随机产生字符串。

DELIMITER //
CREATE FUNCTION rand_string1(n INT)
    RETURNS VARCHAR(255)
BEGIN
    DECLARE chars_str VARCHAR(100) DEFAULT 
        'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    DECLARE return_str VARCHAR(255) DEFAULT ``;
    DECLARE i INT DEFAULT 0;
    WHILE i < n DO
        SET return_str = CONCAT(return_str, 
            SUBSTRING(chars_str, FLOOR(1 + RAND() * 52), 1));
        SET i = i + 1;
    END WHILE;
    RETURN return_str;
END //
DELIMITER ;

创建存储过程,往s1表中插入数据的存储过程:

DELIMITER //
CREATE PROCEDURE insert_s1 (IN min_num INT (10),
                    IN max_num INT (10))
BEGIN
    DECLARE i INT DEFAULT 0;
    SET autocommit = 0;
    REPEAT
    SET i = i + 1;
    INSERT INTO s1 VALUES(
        (min_num + i),
        rand_string1(6),
        (min_num + 30 * i +5),
        rand_string1(6),
        rand_string1(10),
        rand_string1(5),
        rand_string1(10),
        rand_string1(10),
    UNTIL i = max_num
    END REPEAT;
    COMMIT;
    );
END //
DELIMITER ;

创建存储过程,往s2表中插入数据的存储过程:

DELIMITER //
CREATE PROCEDURE insert_s2 (IN min_num INT (10),
                    IN max_num INT (10))
BEGIN
    DECLARE i INT DEFAULT 0;
    SET autocommit = 0;
    REPEAT
    SET i = i + 1;
    INSERT INTO s2 VALUES(
        (min_num + i),
        rand_string1(6),
        (min_num + 30 * i +5),
        rand_string1(6),
        rand_string1(10),
        rand_string1(5),
        rand_string1(10),
        rand_string1(10),
    UNTIL i = max_num
    END REPEAT;
    COMMIT;
    );
END //
DELIMITER ;

调用存储过程: s1表和s2表数据增加1万条记录。

CALL insert_s1(1, 10000);
CALL insert_s2(1, 10000);

下面使用EXPLAIN分析。

table

不论查询语句有多复杂,里边包含了多少个表,到最后也是需要对每个表进行单表访问的,所以MySQL规定EXPLAIN语句输出的每条记录都对应着某个单表的访问方法,该条记录的table列代表着该表的表名(有时可能是简称)。

今天先学习到这里,明天继续。