对于join操作,MySQL它是咋做的?
首先我们对于join操作,需要了解两个概念:驱动表和被驱动表。首先先给出两张表:
CREATE TABLE `t2` (
`id` int(11) NOT NULL,
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `a` (`a`)
) ENGINE=InnoDB; drop procedure idata;
delimiter ;;
create procedure idata()
begin
declare i int;
set i=1;
while(i<=1000)do
insert into t2 values(i, i, i);
set i=i+1;
end while;
end;;
delimiter ;
call idata(); create table t1 like t2;
insert into t1 (select * from t2 where id<=100)
t1数据100行,t2数据1000行,a字段有索引,b字段无索引。
select * from t1 straight_join t2 on (t1.a=t2.a);// 在执行该sql时,t1被强制性作为驱动表,而t2就是被驱动表了
这条语句执行过程是先对t1全表扫,拿到每一行数据的a值,然后作为搜索条件到t2表里进行搜索,以为b有索引并且b的值不重复,所以认为扫表(回表)次数就是100+1000(因为走索引很快并且只要找到对应的t2的a之后只需要回表一次),ok,扫表次数:N+M。
之后再看复杂度,首先t1的扫表次数是N,其次每一个t1的行在t2里都需要做两次索引查找操作,可以认为是N*2*logM,因此复杂度为:N+N*2*logM。
由此可见,当小表作为驱动表时,复杂度会小很多!但是这是在被驱动表t2的a值有索引的情况下,如果没有索引,t2就只能全表扫描了,这种情况下建议立马考虑索引问题,虽然说mysql对此有它自己的优化方案:Block Nested Loop
我们可以再看一看对于驱动表没有索引的情况下再采用上面的方式,扫表次数以及判断复杂度的不同:
(1)扫表:t1还是继续他的N次扫表,然后t2就大有不同了,因为缺少了索引,导致只能走全表扫描也就是M次,那也就是相当暴力的N+N*M次扫表,这个时候不论大表做驱动还是小表做驱动,扫表次数都一样。。。
(2)数据判断复杂度:t2直接全表扫,N+N*M。。
通过上面的判断,发现做法“惊为天人”!于是乎,mysql是这样来优化的,在扫描行数上,驱动表因为一般是小表,可以一次性加载到内存中,然后把判断值的操作放到内存中执行(有索引的话,判断操作是在磁盘里走索引判断),也就是说每次都做t2的全表扫,然后这些M和每一个t1的值做匹配,也就是在扫表次数上比上一个要好很多:N+M,但是在判断的时间复杂度来看,其实还是N*M,但是由于是在内存操作,所以在时间上会弥补很多!!但是由于join_buffer的大小有限制,所以很多时候t1的数据不能一次性加载进来,所以在这个操作过程中t2表可能会被扫好几次,这个是由t1要加载到buffer几次而决定,加载的越多,t2的扫表次数越多,所以buffer的空间越大越好!!
而有关mysql决定哪些表是否是小表而来做驱动时,有他自己的选择方案:可能有些表的数据很大,但是因为有某些where条件而使得真实加载到buffer的数据很少,mysql也就很有可能选择它做小表,或者说是某些表在select后面的条件很少,例如select t1.*,t2.b 这种,因为t2所需要的数据很少,因此可以剩下更多的buffer空间,减少加载buffer的次数,所以t2也很有可能被当作小表而当作驱动表!!
对于join操作,MySQL它是咋做的?的更多相关文章
- MySQL JOIN操作报错问题小解
1 问题描述 在调用一个MySQL存储过程的时候,有时候会出现下面的错误: Illigal mix of collations(gbk\_chinese\_ci, IMPLICIT) and (lat ...
- mysql的join操作
一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona table1 ...
- Code First操作Mysql数据库
前面博客也讲了,自己做一个网站,选用的是MVC+EF Code First+MySql+EasyUI,先说下技术选型.一.为什么选择MVC? 因为之前自己做的系统大部分是webForm,MVC的之前也 ...
- Python自动化运维之18、Python操作 MySQL、pymysql、SQLAchemy
一.MySQL 1.概述 什么是数据库 ? 答:数据的仓库,和Excel表中的行和列是差不多的,只是有各种约束和不同数据类型的表格 什么是 MySQL.Oracle.SQLite.Access.MS ...
- .NET Core Dapper操作mysql数据库
前言 现在ORM盛行,市面上已经出现了N款不同的ORM套餐了.今天,我们不谈EF,也不聊神马黑马,就说说 Dapper.如何在.NET Core中使用Dapper操作Mysql数据库呢,让我们跟随镜头 ...
- 【Python之路】第十九篇--Python操作MySQL
本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...
- (独孤九剑)---PHP操作MySQL数据库
[一]开启mysql扩展 在PHP操作MySQL数据库之前,要保证开启了MySQL数据库扩展 若未开启,则可以将php.int文件下的php_mysql开启即可,方式为去掉前面的封号; 配置完成后要重 ...
- 小白两篇博客熟练操作MySQL 之 第二篇
小白两篇博客熟练操作MySQL 之 第二篇 一. 视图 视图是一个虚拟表,其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集, 并可以将其当做表来使用. s ...
- GO学习-(23) Go语言操作MySQL + 强大的sqlx
Go语言操作MySQL MySQL是业界常用的关系型数据库,本文介绍了Go语言如何操作MySQL数据库. Go操作MySQL 连接 Go语言中的database/sql包提供了保证SQL或类SQL数据 ...
随机推荐
- Javascript中new的作用
关于js中new关键字的理解,先来看个例子:像这样创建实例时使用new与不使用new有什么区别????function ParasiticPerson(name, age, job) { var ...
- Linux环境下MySql安装和常见问题的解决
MySql安装 首先当然是要连接上linux服务器咯,然后就是下面的命令甩过去,梭哈,一通运行就是啦 梭哈 下载: sudo wget http://dev.mysql.com/get/mysql ...
- K2 BPM_携手东航物流,领跑全球航空物流业_全球领先的工作流引擎
现代物流产业正在世界范围内广泛兴起,物流产业已成为各个国家国民经济发展的动脉和基础产业.随着物流新格局的加速形成,商业竞争的核心要素已经从传统的对资产资源的占有,演化为对资本.人才与技术的争夺,流量. ...
- Oracle权限管理详解(1)
详见:https://www.cnblogs.com/yw0219/p/5855210.html Oracle 权限 权限允许用户访问属于其它用户的对象或执行程序,ORACLE系统提供三种权限:Obj ...
- Maven基本概念——根目录、项目创建、坐标
转载来自:https://www.cnblogs.com/zjfjava/p/6817793.html 尊重原创! (一)Maven 基本概念——根目录.项目创建.坐标 1. MavenProj ...
- 揭秘如何用Python黑掉智能锅炉
引文 去年我买了一个新的冷凝式锅炉(家用取暖产品),于是考虑上面必须有一个“智能恒温器”,而选择也很多,包括Google Nest. Hive(英国天然气公司设计的) 以及伍斯特·博世‘Wave’ ...
- Form组件 cookie和session
django form组件 1.渲染标签 2.校验数据 3.展示信息 第一步需要一个form类 from django import forms class MyForm(forms.Form): n ...
- P2050 [NOI2012]美食节 动态加边加点
修车数据加强版 需要动态加边加点 #include<bits/stdc++.h> using namespace std; const int INF = 0x7f7f7f7f; , MA ...
- C#中 委托和事件的关系
首先,委托 是一个好东西.按我的理解,委托 是针对 方法 的更小粒度的抽象.比较interface,他精简了一些代码.使得 订阅-通知 (观察者模式)的实现变得非常简洁. 关于事件,我最初的理解是:事 ...
- springboot同时支持访问html5和jsp时,导致后台ResponseBody返回中文乱码
背景:原系统是由springboot jsp,所有访问都是jsp 现在需要做HTML5定位,要同时支持访问HTML5和JSP 在application.yml的spring标签下配置 mvc: #vi ...