MySQL

83-实战-MySQL-单表-索引-排序的爱恨情仇

2023-02-27  本文已影响0人  紫荆秋雪_文

一、数据准备

CREATE TABLE person_info
(
    id           INT          NOT NULL AUTO_INCREMENT,
    name         VARCHAR(100) NOT NULL,
    birthday     DATE         NOT NULL,
    phone_number CHAR(11)     NOT NULL,
    country      VARCHAR(100) NOT NULL,
    PRIMARY KEY (id),
    KEY idx_name_birthday_phone_number (name, birthday, phone_number)
);
SHOW INDEX FROM person_info;
image.png

1.1、使用存储过程写入数据


DELIMITER $
CREATE PROCEDURE insert_persion(start INT, max_num INT)
BEGIN
    DECLARE i INT DEFAULT 0;
    SET autocommit = 0; #  设置手动提交事务
    REPEAT
        #循环
        SET i = i + 1; #  赋值
        INSERT INTO person_info (name, birthday, phone_number, country)
        VALUES (rand_string(6), DATE_ADD('2021-01-01 00:00:00', INTERVAL FLOOR(1 + (RAND() * 10800)) DAY), rand(10) * 100000000000, rand_num(1, 1000));
    UNTIL i = max_num
        END REPEAT;
    COMMIT; #  提交事务
END $
DELIMITER ;
CALL insert_persion(1, 1000000);

二、 用于排序

2.1、使用索引字段排序

SELECT *
FROM person_info
ORDER BY name, birthday, phone_number;
全表扫描.png

2.2、使用索引字段排序,并且限制 LIMIT

SELECT *
FROM person_info
ORDER BY name, birthday, phone_number
LIMIT 10;
使用了索引.png

2.3、使用索引字段排序,不需要回表,直接使用覆盖索引

SELECT id, name, birthday, phone_number
FROM person_info
ORDER BY name, birthday, phone_number;
使用了索引.png

小结

1、例子(2.1)和例子(2.2)对比

这个两个SQL都是需要查询表的所有信息,而排序使用的是二级索引idx_name_birthday_phone_number。所以需要回表查询优化器会自动判断这个回表成本,如果判断成本大(2.1),就会直接选择全表扫描。由于(2.2)中使用了LIMIT限制了查询数据量,所以查询优化器判断回表成本较小,所以选择使用二级索引idx_name_birthday_phone_number

2、例子(2.1)和例子(2.3)对比
3、书写SQL需要注意

三、用于分组

四、如何挑选索引(适合做索引的列)

上一篇下一篇

猜你喜欢

热点阅读