单表和连表?如何选择?

简介: 单表和连表?如何选择?

快乐,使生命得以延续。快乐,是精神和肉体的朝气,是希望和信念,是对自己的现在和来来的信心,是一切都该如此进行的信心。——果戈理

今天做了个小测试啊

我自己造了一百万多条(1029708条)数据

这里测试呢我们首先是编写了一个LEFT JOIN

连表SQL如下

SELECT *
FROM `film`
         LEFT JOIN `language` ON `film`.language_id = `language`.language_id

我们查询一百万多条后耗时为33457.8317 ms,大约30来秒,这是没有加索引的情况下

我们使用单表查询,然后再拼装

long startTime = System.nanoTime();
List<Film> films = filmMapper.selectList(Wrappers.lambdaQuery());
List<Integer> languageIds = films.parallelStream().map(Film::getLanguageId).distinct().collect(Collectors.toList());
final Map<Integer, Language> languageMap = languageMapper.selectList(Wrappers.lambdaQuery(Language.builder().build()).in(Language::getLanguageId, languageIds)).parallelStream().collect(Collectors.toMap(Language::getLanguageId, Function.identity(), (v1, v2) -> v2));
List<Map<String, Object>> collect = films.stream().map(film -> {
    Map<String, Object> map = BeanUtils.beanToMap(film);
    Optional.ofNullable(film).map(Film::getLanguageId).map(languageMap::get).map(BeanUtils::beanToMap).ifPresent(map::putAll);
    return map;
}).collect(Collectors.toList());
long endTime = System.nanoTime();
System.out.println("耗时:" + ((endTime - startTime) / (1000.0 * 1000.0)) + " ms");

最后耗时为22289.5385 ms,大约20来秒,可以看到明显比上面的连表查询要快

那么如果再连一次呢,模拟两个LEFT JOIN的场景

SELECT *
FROM `film`
         LEFT JOIN `language` ON `film`.language_id = `language`.language_id
         LEFT JOIN `language` AS language1 ON `film`.language_id = language1.language_id

这里耗时37053.9295 ms,因为我们language表数据量较小,所以再连一次差别也并不是特别大

但可以明显看出,多了4秒左右

我们写成单表的话

long startTime = System.nanoTime();
     List<Film> films = filmMapper.selectList(Wrappers.lambdaQuery());
     List<Integer> languageIds = films.parallelStream().map(Film::getLanguageId).distinct().collect(Collectors.toList());
     CompletableFuture<Map<Integer, Language>> languageMapFuture = CompletableFuture.supplyAsync(() -> languageMapper.selectList(Wrappers.lambdaQuery(Language.builder().build()).in(Language::getLanguageId, languageIds)).parallelStream().collect(Collectors.toMap(Language::getLanguageId, Function.identity(), (v1, v2) -> v2)));
     CompletableFuture<Map<Integer, Language>> languageMapFuture1 = CompletableFuture.supplyAsync(() -> languageMapper.selectList(Wrappers.lambdaQuery(Language.builder().build()).in(Language::getLanguageId, languageIds)).parallelStream().collect(Collectors.toMap(Language::getLanguageId, Function.identity(), (v1, v2) -> v2)));
     CompletableFuture.allOf(languageMapFuture, languageMapFuture1).get();
     Map<Integer, Language> languageMap = languageMapFuture.get();
     Map<Integer, Language> languageMap1 = languageMapFuture1.get();
     List<Map<String, Object>> collect = films.stream().map(film -> {
         Map<String, Object> map = BeanUtils.beanToMap(film);
         Optional.ofNullable(film).map(Film::getLanguageId).map(languageMap::get).map(BeanUtils::beanToMap).ifPresent(map::putAll);
         Optional.ofNullable(film).map(Film::getLanguageId).map(languageMap1::get).map(BeanUtils::beanToMap).ifPresent(map::putAll);
         return map;
     }).collect(Collectors.toList());
     long endTime = System.nanoTime();
     System.out.println("耗时:" + ((endTime - startTime) / (1000.0 * 1000.0)) + " ms");

执行后耗时23362.9739 ms!!发现仅仅多了一秒左右啊

上面的连表SQL,就算在language表的language_id上加了索引,也是耗时35314.184 ms

也远远没有我们的单表快

所以结论:

同样的数据,单表多次查询在正确使用下,比连表确实快不少

但连表只需要一条SQL而单表需要写一大堆代码

相关文章
|
SQL 关系型数据库 MySQL
MySQL数据库练习题(单表查询,多表关联查询)(一)
MySQL数据库练习题(单表查询,多表关联查询)
548 0
|
5月前
|
存储 中间件 数据库连接
|
6月前
分库分表中间表优化
【7月更文挑战第21天】
43 2
|
关系型数据库 MySQL 数据库
MySQL数据库练习题(单表查询,多表关联查询)(二)
MySQL数据库练习题(单表查询,多表关联查询)(二)
213 0
|
6月前
|
关系型数据库 MySQL 数据库
MySQL数据库—查询:关联查询(一篇教会你在多表关联下查询数据)
MySQL数据库—查询:关联查询(一篇教会你在多表关联下查询数据)
315 0
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库—多表设计与关联查询
MySQL数据库—多表设计与关联查询
|
关系型数据库 MySQL 数据库
【MySQL速通篇001】MySQL主键,自增列,各类索引,外键及变种,分组,连表,数据行操作等知识点 1
【MySQL速通篇001】MySQL主键,自增列,各类索引,外键及变种,分组,连表,数据行操作等知识点
376 0
|
关系型数据库 MySQL 数据库
【MySQL速通篇001】MySQL主键,自增列,各类索引,外键及变种,分组,连表,数据行操作等知识点 2
【MySQL速通篇001】MySQL主键,自增列,各类索引,外键及变种,分组,连表,数据行操作等知识点
160 0
|
SQL 缓存 关系型数据库
多表联查对比多次单表
只有聪明人才能看见的摘要~( ̄▽ ̄~)~
188 0
|
SQL 存储 缓存
霜皮剥落紫龙鳞,下里巴人再谈数据库SQL优化,索引(一级/二级/聚簇/非聚簇)原理
举凡后端面试,面试官不言数据库则已,言则必称SQL优化,说起SQL优化,网络上各种“指南”和“圣经”难以枚举,不一而足,仿佛SQL优化已然是妇孺皆知的理论常识,然后根据多数无知(Pluralistic ignorance)理论,人们印象里觉得多数人会怎么想怎么做,但这种印象往往是不准确的。那SQL优化到底应该怎么做?本次让我们褪去SQL华丽的躯壳,以最浅显,最粗俗,最下里巴人的方式讲解一下SQL优化的前因后果,前世今生。
霜皮剥落紫龙鳞,下里巴人再谈数据库SQL优化,索引(一级/二级/聚簇/非聚簇)原理