Java深入进阶

sql 百万级数据量查询优化

2019-10-25  本文已影响0人  墙上藤蔓
create table `test1` (
    `id` bigint(10) primary key NOT NULL DEFAULT '0',
    `name` varchar(20) NOT NULL DEFAULT '' comment '用户名',
    `card_no` bigint(18) NOT NULL DEFAULT '0' comment '学号',
    `age` int(2) NOT NULL DEFAULT '0' comment '年龄',
    `sex` TINYINT(1) NOT NULL DEFAULT '0' comment '性别',
    `amount` decimal(18,4) NOT NULL DEFAULT '0.0000',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
)

create table `test2` (
    `id` bigint(10) primary key NOT NULL DEFAULT '0',
    `name` varchar(20) NOT NULL DEFAULT '' comment '用户名',
    `card_no` bigint(18) NOT NULL DEFAULT '0' comment '学号',
    `year` int(2) NOT NULL DEFAULT '0' comment '年龄',
    `sex` TINYINT(1) NOT NULL DEFAULT '0' comment '性别',
    `money` decimal(18,4) NOT NULL DEFAULT '0.0000',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
)
// 将满足条件的两张表数据一起显示出来
SELECT 
    a.name as name,
    a.age as age,
    a.amount as money
    FROM test1 a
    WHERE
        a.card_no in (xxx)
        and
        a.sex=1
        AND
        a.age>18
UNION all
SELECT 
    b.name as name,
    b.card_no as idCard,
    b.year as age,
    b.money as money
    FROM test2 b
    WHERE
        b.card_no in (xxx)
        and
        b.sex=1
        AND
        b.year>18

优化sql开始

以上三点几十万的数据已经能接受了

此时100万的数据耗时4s

重点

// eg.添加单列索引
alter table test1  add INDEX idx_card_no(`card_no`) COMMENT '学号'

// 这里使用多列索引
// 注意索引的创建顺序需要与查询条件顺序一致
// 表1
alter table test1  add INDEX idx_card_no_sex_age(`card_no`,`sex`,`age`) COMMENT '学号-性别-年龄'
// 表2
alter table test2  add INDEX idx_card_no_sex_year(`card_no`,`sex`,`year`) COMMENT '学号-性别-年龄'
此时100万的数据耗时2.5s
drop index index_name on table_name ;

alter table table_name drop index index_name ;

alter table table_name drop primary key ;

划红线的列显示会用到其他索引,这中间有个索引匹配过程,因此会耗时

那如果我指定单独的索引是不是会减少匹配的消耗呢?(可以

SELECT 
    a.name as name,
    a.age as age,
    a.amount as money
    FROM test1 a
    
    USE INDEX(idx_card_no_sex_age)
    
    WHERE
        a.card_no in (xxx)
        and
        a.sex=1
        AND
        a.age>18
UNION all
SELECT 
    b.name as name,
    b.card_no as idCard,
    b.year as age,
    b.money as money
    FROM test2 b
    
    USE INDEX(idx_card_no_sex_year)
    
    WHERE
        b.card_no in (xxx)
        and
        b.sex=1
        AND
        b.year>18
此时100万的数据耗时不到1s

此时应该可以满足需求了,单表也可借用以上优化方法

欢迎大家提供自己的见解,谢谢!

上一篇 下一篇

猜你喜欢

热点阅读