以小博大外小内大,Db数据库SQL优化之小数据驱动大数据
SQL优化中,有一条放之四海而皆准的既定方针,那就是:永远以小数据驱动大数据。其本质其实就是以小的数据样本作为驱动查询能够优化查询效率,在SQL中,涉及到不同表数据的连接、转移、或者合并,这些操作必须得有个数据集作为“带头”大哥,即驱动数据,而这个驱动数据最好是数据量最小的那一个。
内大外小
在讨论数据库之前,日常开发中,我们经常会遇到数据样本数量不一致,但是需要进行检索的情况,比如某人在地铁的某节车厢里捡到N台Iphone,而车厢里正好有T个人,他应该怎么去检索双样本数据,从而找到失主?
for (int i = 0; i < N; i++)
for (int j = 0; j < T; j++)
find();
一般的说法是把循环次数少的循环放在外面,其实,这个问题的主要原因是CPU内部的指令执行机制。现在,基本上CPU内部都有分支指令预测,就是当执行(现在大多将这一阶段提前到预取指令时执行)到转移指令时,都会直接从分支目标缓存(BTB)中取出目标指令的地址,然后将要执行的指令提前预取到CPU的指令预取指令队列中。这样,显然大大提高了效率。一个N次的一层循环在执行时,除了在第一次和最后一次会预测错误外,其他N-i次都会预取成功,避免了执行转移指令时重新取出新指令造成的时间浪费。 所以,当有两层循环,外层循环数为N,内层为T,N远大于T,那么最终造成的预测错误数为N*2+2,而如果外层数为T,内层数为N,预测错误数为T*2+2,显然后者要节省更多时间,而且这个时间是很可观的。N比T越大,这个时间差越明显。
连表查询
回到数据库场景,连表查询操作本质上其实就是扫描驱动表数据,根据条件,逐一去大表找数据,由小表作为驱动表,小表数据少,那么去大表找数据时,能减少数据的找寻量。体现在底层上也就减少了网络的IO,内存,自然效率就高。
不同的连表方式也会有不同的驱动表,左连接中左边为驱动表,右边为被驱动表;右连接中右边为驱动表,左边为被驱动表;内连接中Mysql会选择数据量比较小的表作为驱动表,大表作为被驱动表。我们也可以通过EXPLANIN关键字查看SQL语句的执行计划,从而搞清楚一次连表查询中的驱动表到底是那一张。
底层原理
连表查询操作时,数据库会从头到尾扫描驱动表,复杂度为O(n),也就是说有N条就要查N次,随后再逐一去其它关联表查询数据,众所周知,由于Mysql采用B+tree方式进行存放数据,关于B+tree,请移步:霜皮剥落紫龙鳞,下里巴人再谈数据库SQL优化,索引(一级/二级/聚簇/非聚簇)原理,因此查询时间复杂度为O(logn),总时间复杂度即为O(n)*O(logn),说白了就是驱动数据集有多少条数据,就得在B+tree中查询O(logn)次。
假设表n数据小于表m,则连表查询操作时,O(n)*O(logm) 小于 O(m)*O(logn),因此小数据集作为驱动数据相对就比较有效率。
子查询
外小内大原则也同样适用于子查询,当子表的数据集较小时,使用In操作,效率较高:
SELECT * FROM A WHERE ID IN (SELECT ID FROM B)
这里B表的数据量小于A表数据,很明显B表作为查询筛选的驱动表。
反之,当B表数据量大于外侧的数据表A:
SELECT * FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.ID = A.ID)
此时使用EXISTS的效率更高,因为EXISTS是将主查询的数据放到子查询中做条件验证,根据验证结果(TRUE或者FALSE)来决定主查询的数据结果是否能够得以保留。
结语
循环嵌套优化原则的外小内大,数据库SQL优化原则的以小博大,一脉相承,同出一辙,大道至简,殊途同归。
以小博大外小内大,Db数据库SQL优化之小数据驱动大数据的更多相关文章
- 数据库SQL优化大总结之 百万级数据库优化方案(转载)
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
- 数据库sql优化总结之5--数据库SQL优化大总结
数据库SQL优化大总结 小编最近几天一直未出新技术点,是因为小编在忙着总结整理数据库的一些优化方案,特此奉上,优化总结较多,建议分段去消化,一口吃不成pang(胖)纸 一.百万级数据库优化方案 1.对 ...
- 数据库SQL优化大总结之百万级数据库优化方案
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
- (转)数据库SQL优化大总结之 百万级数据库优化方案
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
- 数据库 SQL 优化大总结之:百万级数据库优化方案
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
- 数据库SQL优化大总结之百万级数据库优化方案(转)
add by zhj: 作者没有指定是哪个数据库,这只是一个近似通用的总结.对于某个特定的数据库,有些条目可能并不适用. 原文:http://www.cnblogs.com/yunfeifei/p/3 ...
- 【数据库】百万级数据库SQL优化大总结
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
- 数据库SQL优化大总结之 百万级数据库优化方案(转)
出处:http://www.cnblogs.com/yunfeifei/p/3850440.htm 网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不 ...
- 数据库SQL优化大总结之 百万级数据库优化方案 【转载】
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
- 百万级数据库SQL优化大总结
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...
随机推荐
- Springboot 加密方案探讨
背景 toB 的本地化 java 应用程序,通常是部署在客户机器上,为了保护知识产权,我们需要将核心代码(例如 Lience,Billing,Pay 等)进行加密或混淆,防止使用 jadx 等工具轻易 ...
- 【Unity3D】Shader Graph简介
1 Shader Graph 简介 Shader Graph 是 Unity 官方在 2018 年推出的 Shader 制作插件,是图形化的 Shader 制作工具,类似于 Blender 中的 ...
- 2023 版 Java和python开发线性代数探索
目录 前景提示 需求 分析 1.初始化不需要指定矩阵的尺寸,并且可以直接传入数据. 2.可以计算2x2矩阵的逆 3.可以做2x2的矩阵乘法 Java版本开发 一. 开发详情 1.开发一个子类,如图所示 ...
- NFT(数字藏品)热度没了?这玩意是机会还是泡沫?
感谢你阅读本文! 大家好,今天分享一下NFT(数字藏品)这个领域,虽然今天的NFT已经没有之前那么火热,不过市场上依旧还是有很多平台存在,有人离开,也有人不断进来,所以很有必要再分析一番. 需要注意的 ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-23-处理select下拉框-下篇
1.简介 上一篇中宏哥主要讲解和分享了一下,我们常见或者传统的select下拉框的操作,但是近几年又出现了了一种新的select下拉框,其和我们传统的select下拉框完全不一样,那么我们如何使用pl ...
- GameFramework摘录 - 1. ReferencePool
GameFramework是一个结构很优秀的Unity游戏框架,但意图似乎在构建可跨引擎的框架?对要求不高的小型个人(不专业)开发来说有些设计过度了,但其中的设计精华很值得学习. 首先来说一下其中的R ...
- HTTP 和 RPC 的区别
一句话概括 RPC代表:Feign.Dubbo RPC 主要用于公司内部的服务调用,性能消耗低,传输效率高,服务治理方便. HTTP 代表:RestTemplate.HttpClient HTTP 主 ...
- 鸿蒙开发学习(一)之ArkTS
目录 TypeScript语法 基础 module ArkTS 基本UI描述 基本概念 状态管理 页面级变量的状态管理 @State @Prop @Link 应用级变量的状态管理 开发入门 应用模型 ...
- Meissel–Lehmer 算法
前言 推荐先行阅读我的blog文章----Min_25 筛 什么是Meissel–Lehmer 算法 Meissel-Lehmer 算法是一种基于 \(ϕ\) 函数的的快速计算前缀质数个数(当然也可以 ...
- go 上下文:context.Context
Go语言中的上下文(Context)是一种用于在 Goroutines 之间传递取消信号.截止时间和其他请求范围值的标准方式.context 包提供了 Context 类型和一些相关的函数,用于在并发 ...