sql优化

mysql 查询优化 ~ 多表查询基础知识

99封情书 提交于 2020-01-16 06:51:34
一 什么是驱动表 1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表]; 2)未指定联接条件时,行数少的表为[驱动表](Important!)。 表现 explain第一行出现的就是驱动表 二 多表查询的分类 1 多表join查询 2 多表join+子查询 三 驱动表的分类 1 单表 单表执行顺序有2种情况 1 单表先执行条件过滤,结算出结果再进行关联join 2 单表先进行关联join,再结果进行条件过滤 可以根据explain驱动表的索引选择进行判断是根据哪种情况执行 1 选择条件索引,先过滤 2 选择连接字段索引,先关联 2 派生表 explain->type-><derived>名称 即为派生表 eg SELECT column_list FROM (SELECT column_list FROM table_1) derived_table_nameWHERE derived_table_name.column > 1 注意 执行的是 select from之后 where和join之前的语句 执行顺序 1 执行子查询的内容 2 把子查询的结果写到临时表中 3 回读,应用上层SELECT的WHERE条件 四 多表查询几点注意 1 对驱动表可以直接排序,对非驱动表(的字段排序)需要对循环查询的合并结果(临时表)进行排序 2 一旦连接字段没有应用索引

sql经验总结

两盒软妹~` 提交于 2020-01-16 03:11:01
最近正在做 美女图片 站,经常用到数据库 (1) 选择最有效率的表名顺序 (只在基于规则的优化器中有效): ORACLE 的解析器按照从右到左的顺序处理 FROM 子句中的表名,FROM 子句中写在最后的表 (基础表 driving table) 将被最先处理,在 FROM 子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有 3 个以上的表连接查询, 那就需要选择交叉表 (intersection table) 作为基础表,交叉表是指那个被其他表所引用的表。 (2) WHERE 子句中的连接顺序.: ORACLE 采用自下而上的顺序解析 WHERE 子句, 根据这个原理,表之间的连接必须写在其他 WHERE 条件之前, 那些可以过滤掉最大数量记录的条件必须写在 WHERE 子句的末尾。 (3) SELECT 子句中避免使用 ‘ * ‘: ORACLE 在解析的过程中,会将’*’ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。 (4) 减少访问数据库的次数: ORACLE 在内部执行了许多工作: 解析 SQL 语句,估算索引的利用率,绑定变量, 读数据块等。 (5) 在 SQL*Plus , SQL*Forms 和 Pro*C 中重新设置 ARRAYSIZE 参数, 可以增加每次数据库访问的检索数据量 , 建议值为 200。

SQL SARG

让人想犯罪 __ 提交于 2020-01-16 02:34:33
很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解。比如: select * from table1 where name='zhangsan' and tID > 10000 和执行: select * from table1 where tID > 10000 and name='zhangsan' 一些人不知道以上两条语句的执行效率是否一样,因为如果简单的从语句先后上看,这两个语句的确是不一样,如果tID是一个聚合索引,那么后一句仅仅从表的10000条以后的记录中查找就行了;而前一句则要先从全表中查找看有几个name='zhangsan'的,而后再根据限制条件条件tID>10000来提出查询结果。 事实上,这样的担心是不必要的。SQL SERVER中有一个“查询分析优化器”,它可以计算出where子句中的搜索条件并确定哪个索引能缩小表扫描的搜索空间,也就是说,它能实现自动优化。 虽然查询优化器可以根据where子句自动的进行查询优化,但大家仍然有必要了解一下“查询优化器”的工作原理,如非这样,有时查询优化器就会不按照您的本意进行快速查询。 在查询分析阶段,查询优化器查看查询的每个阶段并决定限制需要扫描的数据量是否有用。如果一个阶段可以被用作一个扫描参数(SARG),那么就称之为可优化的

MySql下实现先排序后分组

心不动则不痛 提交于 2020-01-16 02:31:36
对比可以发现5.7版本的MySql在执行这条sql时缺少了一个derived操作,通过查阅相关资料了解到MySql 5.7对子查询进行了优化,认为子查询中的order by可以进行忽略,只要Derived table里不包含如下条件就可以进行优化: UNION clause GROUP BY DISTINCT Aggregation LIMIT or OFFSET 这里把链接放上:5.7中Derived table变形记 最后放上相应的解决办法: --方法一,仅适用于低于5.7版本的MySql-- select * from (select * from shop order by price desc) a GROUP BY a.shop_name; --方法二-- select * from (select * from shop order by price desc limit 999999) a GROUP BY a.shop_name; --方法三-- select * from shop a where N > (select count(*) from shop b where b.shop_name = a.shop_name and a.price < b.price) order by a.shop_name,a.price desc; 1 2 3 4 5 6

MySQL逻辑分层

风流意气都作罢 提交于 2020-01-16 01:42:59
  连接层:提供与客户端连接的服务   服务层:  1.提供各种用户使用的接口         2.提供sql优化器   引擎层:提供了各种存储数据的方式(InnoDB,MylSAM)   存储层:存储数据   存储引擎的主要区别   InnoDB(默认引擎):事务优先(适合高并发性操作,行锁)   MylSAM:性能优先(表锁)   查看数据库支持的引擎   show engines;      查询当前使用的引擎   show variables like '%storage_engine%';      指定数据库对象的引擎 engine myisam                来源: https://www.cnblogs.com/starshine-zhp/p/12199400.html

SQL优化

梦想与她 提交于 2020-01-16 01:32:06
原因:性能低、执行时间长、等待时间长、SQL语句欠佳(连接查询)、索引失效、服务器参数不合理(缓冲、多线程);   1.SQL:         编写过程 select ... from ... join ... on ... where ... group by ... having ... order by ... limit ...;       解析过程 from ... on ... join ... where ... group by ... having ... select ... order by ... limit ...;   2.SQL优化,主要就是优化索引     索引:index是帮助MYSQL高效获取数据的数据结构,索引熟数据结构(树:B树(默认)、Hash树...)     索引的弊端:         1.索引本身就很大,可以存放在内存/硬盘(通常为硬盘)         2.索引本身不是所有情况都适用  a.少量数据   b.频繁更新的字段   c.很少使用的字段         3.索引会降低增删改的效率     索引的优势:         1.提高查询的效率(降低了IO)的使用率         2.降低cpu的使用率(因为B树索引本来就是排好序的,所以可以直接使用) 来源: https://www.cnblogs.com

MySQL的JOIN(二):JOIN原理

醉酒当歌 提交于 2020-01-16 01:20:29
表连接算法 Nested Loop Join(NLJ)算法: 首先介绍一种基础算法:NLJ,嵌套循环算法。循环外层是驱动表,循坏内层是被驱动表。驱动表会驱动被驱动表进行连接操作。首先驱动表找到第一条记录,然后从头扫描被驱动表,逐一查找与驱动表第一条记录匹配的记录然后连接起来形成结果表中的一条记。被驱动表查找完后,再从驱动表中取出第二个记录,然后从头扫描被驱动表,逐一查找与驱动表第二条记录匹配的记录,连接起来形成结果表中的一条记录。重复上述操作,直到驱动表的全部记录都处理完毕为止。这就是嵌套循环连接算法的基本思想,伪代码如下。 foreach row1 from t1 foreach row2 from t2 if row2 match row1 //row2与row1匹配,满足连接条件 join row1 and row2 into result //连接row1和row2加入结果集 首先加载t1,然后从t1中取出第一条记录,之后加载t2表,与t2表中的记录逐个匹配,连接匹配的记录。 Block Nested Loop Join(BNLJ)算法: 再介绍一种高级算法:BNLJ,块嵌套循环算法,可以看作对NLJ的优化。大致思想就是建立一个缓存区,一次从驱动表中取多条记录,然后扫描被驱动表,被驱动表的每一条记录都尝试与缓冲区中的多条记录匹配,如果匹配则连接并加入结果集。缓冲区越大

MySQL 8.0发布,你熟悉又陌生的Hash Join?

大城市里の小女人 提交于 2020-01-16 00:55:45
昨天下午在查资料的时候,无意间点到了MySQL的官网。发现MySQL发布了一个新版本。 Mysql这个数据库有没有人不熟悉?不用的?没有吧。 2019年末,MySQL发布的8.0.18 GA版本,带来了一些新特性和增强功能。其中最引人注目的莫过于多表连接查询 支持Hash Join 。 还是老样子,建议英文好的同学直接看这里: https://dev.mysql.com/doc/refman/8.0/en/hash-joins.html 关于MySQL Hash Join的特性介绍: 1、对于大数据量的表关联,HJ(Hash Join)速度将明显比NL(Nested Loop)快很多 2、在内存中处理 3、必要情况下,会使用磁盘空间 4、用于内连接,可扩展到外连接、半连接和反连接 5、替换查询计划中的Block Nested Loop 6、可以通过HINT强制SQL走HJ或者NL 有的同学可能已经懵逼了。什么是Hash Join?什么是NL?HINT又是什么鬼? 第一部分先做一个简单的科普 首先,在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式。多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join。 肯定有人说,阿里巴巴规范上都说了,并发情况下不能用多表查询。你有多大并发

SQL语句优化

ε祈祈猫儿з 提交于 2020-01-15 23:57:03
怎么加快查询速度,优化查询效率,主要原则就是应尽量避免全表扫描,应该考虑在where及order by 涉及的列上建立索引。   建立索引不是建的越多越好,原则是:   第一:一个表的索引不是越多越好,也没有一个具体的数字,根据以往的经验, 一个表的索引最多不能超过6个, 因为索引越多,对update和insert操作也会有性能的影响,涉及到索引的新建和重建操作。   第二:建立索引的方法论为: 多数查询经常使用的列; 很少进行修改操作的列; 索引需要建立在数据差异化大的列上   利用以上的基础我们讨论一下如何优化sql.   1、sql语句模型结构优化指导     a. ORDER BY + LIMIT组合的索引优化       如果一个SQL语句形如:SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort] LIMIT [offset],[LIMIT];       这个SQL语句优化比较简单,在[sort]这个栏位上建立索引即可。     b. WHERE + ORDER BY + LIMIT组合的索引优化       如果一个SQL语句形如:SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [VALUE] ORDER BY [sort]

MySQL 查询优化之 Block Nested-Loop 与 Batched Key Access Joins

眉间皱痕 提交于 2020-01-15 23:52:26
MySQL 查询优化之 Block Nested-Loop 与 Batched Key Access Joins 在MySQL中,可以使用批量密钥访问(BKA)连接算法,该算法使用对连接表的索引访问和连接缓冲区。 BKA算法支持 :内连接,外连接和半连接操作,包括嵌套外连接。 BKA的优点 :更加高效的表扫描提高了连接性能。 此外,先前仅用于内连接的块嵌套循环(BNL)连接算法现已扩展,可用于 外连接 和 半连接 操作,包括 嵌套外连接 。 以下部分讨论了连接缓冲区管理,它是原始BNL算法扩展,扩展BNL算法和BKA算法的基础。 有关半连接策略的信息,请参见 “使用半连接转换优化子查询,派生表和视图引用” Nested Loop Join 算法 Block Nested-Loop 算法 Batched Key Access 算法 BNL和BKA算法的优化器Hint Nested Loop Join算法 将外层表的结果集作为循环的基础数据,然后循环从该结果集每次一条获取数据作为下一个表的过滤条件去查询数据,然后合并结果。如果有多个表join,那么应该将前面的表的结果集作为循环数据,取结果集中的每一行再到下一个表中继续进行循环匹配,获取结果集并返回给客户端。 伪代码如下 : for each row in t1 matching range { for each row in t2