2.利用这些主表ID值,分别和几张子表使用IN子句,查询出子表中符合条件的记录项。有几张子表,就执行几次SQL语句。...这么做的弊端是: 由于(1)查出的ID值最多可能会有100个以上,因此子表使用IN子句的时候很有可能导致CBO选择全表扫描,虽然从理论上说,一条SQL未必适用索引扫描效率就一定高,CBO一定是基于现有的统计信息选择一条成本值最低的执行计划...其次是方案2,虽然子表执行SQL次数未变,但通过临时表,可以保证每次检索均可以使用索引快速定位,避免大表的全表扫描,同时临时表特性对应用几乎透明。...创建临时表使用的是CREATE GLOBAL TEMPORARY TABLE语法,ON COMMIT子句则决定了表数据是交易级别还是session级别,默认是交易级别。...可以考虑为临时表建一个独立的临时表空间。
MySQL执行计划是sql语句经过查询优化器后,查询优化器会根据用户的sql语句所包含的字段和内容数量等统计信息,选择出一个执行效率最优(MySQL系统认为最优)的执行计划,然后根据执行计划,调用存储引擎提供的接口...Full scan on NULL key当优化程序无法使用索引查找访问方法时,子查询优化将作为回退策略发生。 Impossible HAVING该HAVING子句始终为false,无法选择任何行。...Impossible WHERE 该WHERE子句始终为false,无法选择任何行。...该信息已从数据字典中获得。 Open_frm_only:只需要读取表信息的数据字典。 Open_full_table:未优化的信息查找。必须从数据字典中读取表信息并读取表文件。...Zero limit 查询有一个LIMIT 0子句,不能选择任何行。 Only index 这意味着信息只用索引树中的信息检索出的,这比扫描整个表要快。
明明已经执行了delete,可表文件的大小却没减小,令人费解 项目中使用Mysql作为数据库,对于表来说,一般为表结构和表数据。表结构占用空间都是比较小的,一般都是表数据占用的空间。...当我们使用 delete删除数据时,确实删除了表中的数据记录,但查看表文件大小却没什么变化。...COPY:复制:使用一种临时表的方式,克隆出一个临时表,在临时表上执行DDL,然后再把数据导入到临时表中,在重命名等。这期间需要多出一倍的磁盘空间来支撑这样的 操作。执行期间,表不允许DML的操作。...OPTIMIZE TABLE 和 ALTER TABLE 表名 ENGINE=INNODB都支持Oline DDL,但依旧建议在业务访问量低的时候使用 总结 delete 删除数据时,其实对应的数据行并不是真正的删除...可以重建表的方式,快速将delete数据后的表变小(OPTIMIZE TABLE 或ALTER TABLE),在 5.6 版本后,创建表已经支持 Online 的操作,但最好是在业务低峰时使用
因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。...在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create...如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。...order by子句:执行顺序从左到右 避免数据类型不一致 读取适当的记录LIMIT M,N 避免在select子语句中使用子查询 对于有联接的列,即使最后的联接值为一个静态值,优化器是不会使用索引的...被程序语句获得的锁 redo log buffer 中的空间 ORACLE为管理上述3种资源中的内部花费 避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤.
在参与实际项目中,当 MySQL 表的数据量达到百万级时,普通的 SQL 查询效率呈直线下降,而且如果 where 中的查询条件较多时,其查询速度无法容忍。...4、内存不足 5、网络速度慢 6、查询出的数据量过大(可采用多次查询,其他的方法降低数据量) 7、锁或者死锁(这是查询慢最常见的问题,是程序设计的缺陷) 8、sp_lock,sp_who,活动的用户查看...因为 SQL 只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择到运行时;它必须在编译时进行选择。然而,如果在编译时简历访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。...23、在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先 create...24、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
Copy算法 按照原表定义创建一个新的临时表 对原表加写锁(禁止 DML,允许 select) 步骤 1)建立的临时表执行 DDL 将原表中的数据 copy 到临时表 释放原表的写锁 将原表删除,并将临时表重命名为原表...而如果我担心它选择了锁而导致我们的表不能读也不能写,显然这不是我们想要的结果,我们希望:如果选择了锁就不要执行,直接退出执行;如果没有选择锁就执行。想要达到我们希望的这个效果,该怎么做呢?...COPY:复制:使用一种临时表的方式,克隆出一个临时表,在临时表上执行DDL,然后再把数据导入到临时表中,在重命名等。这期间需要多出一倍的磁盘空间来支撑这样的 操作。执行期间,表不允许DML的操作。...最后再次将 MDL S 锁升级为 MDL X 锁,完成 DDL 操作,释放 MDL 锁; 所以在真正执行 DDL 操作期间,确实是不会“锁表”的,但是如果在第一阶段拿 MDL X 锁时无法正常获取,那就可能真的会...此时 session 3 需要执行一个查询,发现无法执行。实际上,在 session 1 结束前,表 t1 的所有操作都无法进行了,也可以说表 t1 “锁表”了。
EXPLAIN命令是查看查询优化器如何决定执行查询的主要方法,但该动能也有局限性,它的选择并不总是最优的,展示的也并不一定是真相。...无法区分具有相同名字的事物,例如,它对内存排序和临时文件排序都使用“filesort”,并且对磁盘上和内存中的临时表都显示“Using temporary”。...id越大执行优先级越高,id相同则认为是一组,从上往下执行,id为NULL最后执行。 例如UNION查询中最后对于临时表的查询,它的id就为null,因为临时表并不在原sql中出现。...通常情况下,它相当表明了:那就是那个表,或者该表的别名。 可以通过该列从上到下观察MySQL的关联优化器为查询选择的关联顺序。...key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的。
执行流程为: 1. 扫描 t1,从 t1 取出一行数据 R; 2. 从数据行 R 中,取出字段 a 执行子查询,如果得到结果为 TRUE,则把这行数据 R 放到结果集; 3....这里 semijoin 优化后的执行流程为: 1. 先执行子查询,把结果保存到一个临时表中,这个临时表有个主键用来去重; 2. 从临时表中取出一行数据 R; 3....这样一来,子查询结果有 9 行,即临时表也有 9 行(这里没有重复值),总的扫描行数为 9+9+9*1=27 行,比原来的 1000 行少了很多。...内存临时表包含主键(hash 索引),消除重复行,使表更小。如果子查询结果太大,超过 tmp_table_size 大小,会退化成磁盘临时表。...不过要注意的是,这样外查询依旧无法通过索引快速查找到符合条件的数据,只能通过全表扫描或者全索引扫描,materialization 优化后的执行计划为: +----+-------------+----
Select--From--Where--Group by--Having--Order by 但这几关键词的执行顺序与sql语句的书写顺序并不是一样的,而是按照下面的顺序来执行 From--Where...--Group by--Having--Select--Order by (有些数据库的实现是先Order by--后Select 但其实只是数据表示先后这不影响数据的筛选) from:需要从哪个数据表检索数据...格式为: SELECT 查询列表序列 INTO 新表名 FROM 数据源 …..其他行过滤、分组等语句 用INTO子句创建的新表可以是永久表,也可以是临时表。...局部临时表通过在表名前边加一个‘#’来表识,局部临时表的生存期为创建此局部临时表的连接的生存期,它只能在创建此局部临时表的当前连接中使用。...全局临时表通过在表名前加‘##’来标识,全局临时表的生存期为创建全局临时表的连接的生存期,并且在生存期内可以被所有的连接使用。
14、写出统一的SQL语句: 对于以下两句SQL语句,很多人都认为是相同的。不过数据库查询优化器则认为是不同的,虽然只是大小写不同,但必须进行两次解析,生成2个执行计划。...将临时结果暂存在临时表,后面的查询就在临时表中查询了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。但是,对于一次性事件,较好使用导出表。...23、在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create...24、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。...下面以employees.employees表为例介绍前缀索引的选择和使用。
7.如果在 where 子句中使用参数,也会导致全表扫描。因为 SQL 只有在运行时才会解析局部变量,但优 化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。...然 而,如果在编译时建立访问计 划,变量的值还是未知的,因而无法作为索引选择的输入项。...23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log 以提高速度;如果数据量不大,为了缓和系统表的资源,应先 create...table,然后 insert. 24.如果使用到了临时表, 在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定...例如: optimize table table_name 注意: analyze、check、optimize执行期间将对表进行锁定,因此一定注意要在MySQL数据库不繁忙的时候执行相关的操作。
(在我测试的表中,数据量为 80 万,当 LIMIT 超过 2 万多时就不再使用索引排序),例如:ORDER BY a LIMIT 100 虽然未遵循最左前缀匹配,但是前导列通过常量进行了查询,例如:WHERE...a = "Paidaxing" ORDER BY b filesort 排序 如果无法使用或优化器认为索引排序效率不高,MySQL 将执行 filesort 操作,以读取表中的行并对它们进行排序。...将排序后的结果集返回给客户端。 以上过程中,如果数据在 sort_buffer 中无法全部存放,则会使用临时文件,并对临时文件进行归并排序。...但其缺点在于,如果要查询的字段较多,会占用大量 sort_buffer 空间,导致可存储的数据量减少。当需要排序的数据量增大时,可能会使用临时文件,从而导致整体性能下降。...根据排序后的 id,回表查询出对应的 a、d、f 几个字段。 将结果集返回给客户端。 以上的第五步,与全字段排序算法相比确实多了一次回表操作。因此,这种方案的效率肯定会稍慢一些。
由于mysql查询只能走一个索引查询,但是为了优化查询效果,在使用2个索引的情况,会分别查询出2个索引的数据,然后合并 (select * form table where index1=xx or index2..., 可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的) 不损失精确性的情况下,长度越短越好...如果使用的是索引执行的单表扫描,那么计算驱动表扇出的时候需要估计出满足除使用到对应索引的搜索条件外的其他搜索条件的记录有多少条的比值。...MySQL 很有可能寻求通过建立内部的临时表来执行查询。... Extra 列将显示 Start temporary 提示 本文为仙士可原创文章,转载无需和我联系,但请注明来自仙士可博客www.php20.cn
当有union时,UNION RESULT的table列的值为 ,1和2表示参与 union 的select行id。...explain 时可能出现 possible_keys 有列,而 key 显示 NULL 的情况,这种情况是因为表中数据不多,MySQL认为索引对此查询帮助不大,选择了全表查询。 ...7. key_len 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的...,但还没有计算在最终的代价中。...(default 1.0) 内部myisam或innodb临时表的行代价; 可以看出创建临时表的代价是很高的,尤其是内部的myisam或innodb临时表。
这篇博客,我们以mysql数据库为例,对一条sql语句的执行流程进行分析。...(图1.0) 现在针对这张student表中的数据提出一个问题:要求查询出挂科数目多于两门(包含两门)的前两名学生的姓名,如果挂科数目相同按学生姓名升序排列。...sql为例来分析一下一条语句的执行流程。...(2)当查询sql中有GROUP BY时,会对内存中的若干临时表分别执行SELECT,而且只取各临时表中的第一条记录,然后再形成新的临时表。...从数据库表文件加载到内存中的原生数据过滤,而HAVING 是对SELECT 语句执行之后的临时表中的数据过滤,所以说column AS otherName ,otherName这样的字段在WHERE后不能使用
; 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符; 临时库表必须以tmp_为前缀并以日期为后缀,备份表必须以bak_为前缀并以日期(时间戳)为后缀; 所有存储相同数据的列名和列类型必须一致...但 truncate table比 delete速度快,且使用的系统和事务日志资源少。 delete语句每次删除一行,并在事务日志中为所删除的每行记录一项。...truncate table通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。 truncate table删除表中的所有行,但表结构及其列、约束、索引等保持不变。...36、关于临时表 避免频繁创建和删除临时表,以减少系统表资源的消耗; 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量...43、禁止在表中建立预留字段 预留字段的命名很难做到见名识义; 预留字段无法确认存储的数据类型,所以无法选择合适的类型; 对预留字段类型的修改,会对表进行锁定; 44、禁止在数据库中存储图片
如果在where子句中使用参数,也会导致全表扫描。因为sql只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时,它必须在编译时进行选择。...然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。...create table,避免造成大量log,以提高速度,如果数据量不大,为了缓和系统表的资源,应先create table,然后insert 20.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除...,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定 21.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写 22.使用基于游标的方法或临时表方法之前...对小型数据集使用FAST_FORWARD游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。
如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。...然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:?...避免频繁创建和删除临时表,以减少系统表资源的消耗。 临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。...在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create...如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。...避免频繁创建和删除临时表,以减少系统表资源的消耗。 临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。...在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create...如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。...与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。
领取专属 10元无门槛券
手把手带您无忧上云