首先我们对于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它是咋做的?的更多相关文章

  1. MySQL JOIN操作报错问题小解

    1 问题描述 在调用一个MySQL存储过程的时候,有时候会出现下面的错误: Illigal mix of collations(gbk\_chinese\_ci, IMPLICIT) and (lat ...

  2. mysql的join操作

    一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona table1 ...

  3. Code First操作Mysql数据库

    前面博客也讲了,自己做一个网站,选用的是MVC+EF Code First+MySql+EasyUI,先说下技术选型.一.为什么选择MVC? 因为之前自己做的系统大部分是webForm,MVC的之前也 ...

  4. Python自动化运维之18、Python操作 MySQL、pymysql、SQLAchemy

    一.MySQL 1.概述 什么是数据库 ? 答:数据的仓库,和Excel表中的行和列是差不多的,只是有各种约束和不同数据类型的表格 什么是 MySQL.Oracle.SQLite.Access.MS ...

  5. .NET Core Dapper操作mysql数据库

    前言 现在ORM盛行,市面上已经出现了N款不同的ORM套餐了.今天,我们不谈EF,也不聊神马黑马,就说说 Dapper.如何在.NET Core中使用Dapper操作Mysql数据库呢,让我们跟随镜头 ...

  6. 【Python之路】第十九篇--Python操作MySQL

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...

  7. (独孤九剑)---PHP操作MySQL数据库

    [一]开启mysql扩展 在PHP操作MySQL数据库之前,要保证开启了MySQL数据库扩展 若未开启,则可以将php.int文件下的php_mysql开启即可,方式为去掉前面的封号; 配置完成后要重 ...

  8. 小白两篇博客熟练操作MySQL 之 第二篇

    小白两篇博客熟练操作MySQL  之   第二篇 一. 视图 视图是一个虚拟表,其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集, 并可以将其当做表来使用. s ...

  9. GO学习-(23) Go语言操作MySQL + 强大的sqlx

    Go语言操作MySQL MySQL是业界常用的关系型数据库,本文介绍了Go语言如何操作MySQL数据库. Go操作MySQL 连接 Go语言中的database/sql包提供了保证SQL或类SQL数据 ...

随机推荐

  1. localStorage、sessionStorage和cookie的区别

    本地客户端(浏览器)查看三者信息: HTML4的本地存储:cookie 浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等根服务端进行数据交互. 一.co ...

  2. ASP.NET---如何使用web api创建web服务

    1 首先创建asp.net web空项目,并且创建模拟数据,我在工程下面创建了一个Models文件夹,在文件夹Nodels下面创建类Product和Repository 具体如下: [Serializ ...

  3. 关于操作git

    手册:http://www.yiibai.com/git/ 一.安装git,可以通过git bash执行命令行:安装tortoiseGit执行git相关操作,在那之前需要了解下git命令行操作 二.在 ...

  4. 安卓开发之利用XmlPullParser解析XML文件

    package com.lidaochen.phonecall; import android.support.v7.app.AppCompatActivity; import android.os. ...

  5. Oracle cmd 命令

    1.登陆 输入sqlplus,回车.然后输入用户名和密码. 退出exit. 2.查看服务 Window打开服务的cmd命令 windows +R :services.msc---本地服务设置 rege ...

  6. 【转载】python format遇上花括号{}

    在format string中, 大括号已经被format占用,想要使用大括号本身,该怎么办? 以下转载自这里. ============ 分割线 ============ 使用format时,字符串 ...

  7. Django框架orm

    一.django目录 二.登录注册 三.三件套 四.orm简介 五.基于orm的用户登录 一.django目录 -settings -urls -views -强调:setting中的'django. ...

  8. Linux磁盘及文件系统管理1

    RHCSA认证中的东西: Linux系统管理包括的内容有: 磁盘分区及文件系统管理 RAID LVM 网络属性管理 程序包管理 sed and awk 进程查看和管理 内核管理(编译和安装) 系统启动 ...

  9. Appium Desired Capabilities-General Capabilities

    Desired Capabilities are keys and values encoded in a JSON object, sent by Appium clients to the ser ...

  10. CentOS7 内核优化 修改参数

    一:内核简介 内核是操作系统最基本的部分.它是为众多应用程序提供对计算机硬件的安全访问的一部分软件,这种访问是有限的,并且内核决定一个程序在什么时候对某部分硬件操作多长时间. 内核的分类可分为单内核和 ...