exists
用于对外表记录做筛选。exists
会遍历外表,将外查询表的每一行,代入内查询进行判断。当exists
里的条件语句能够返回记录行时,条件就为真,返回外表当前记录。反之如果exists
里的条件语句不能返回记录行,条件为假,则外表当前记录被丢弃。
select a.* from A awhere exists(select 1 from B b where a.id=b.id)
in
是先把后边的语句查出来放到临时表中,然后遍历临时表,将临时表的每一行,代入外查询去查找。
select * from Awhere id in(select id from B)
相同点:
truncate
和不带where
子句的delete
、以及drop
都会删除表内的数据。drop
、truncate
都是DDL
语句(数据定义语言),执行后会自动提交。不同点:
where
子句作用于表和视图,having
作用于组。where
在数据分组前进行过滤,having
在数据分组后进行过滤。按照性能排序是:count(*) = count(1) > count(主键字段) > count(字段)
比如说,id是主键字段。
如果表里只有主键索引,没有二级索引时。那么,InnoDB 循环遍历聚簇索引(主键索引),将读取到的记录返回给 server 层,但是不会读取记录中的任何字段的值,因为 count 函数的参数是 1,不是字段,所以不需要读取记录中的字段值。参数 1 很明显并不是 NULL,因此 server 层每从 InnoDB 读取到一条记录,就将 count 变量加 1。
显然,count(1) 相比 count(主键字段) 少一个步骤,就是不需要读取记录中的字段值,所以通常会说 count(1) 执行效率会比 count(主键字段) 高一点。
但是,如果表里有二级索引时,InnoDB 循环遍历的对象就二级索引了。
count(*) 其实等于 count(0),也就是说,当你使用 count(*) 时,MySQL 会将 * 参数转化为参数 0 来处理。
所以,count(*) 执行过程跟 count(1) 执行过程基本一样的,性能没有什么差异。
当进行多表查询时,在 MySQL 中常用的连接方式有以下几种:
还有一个是全外连接(FULL JOIN):返回左右两个表中的所有行。如果某个表中没有匹配的行,对应的列将填充为 NULL。需要注意 MySQL 不支持 FULL JOIN 可以使用UNION ALL 模拟。
最主要的原因就是join的效率比较低:MySQL是使用了嵌套循环(Nested-Loop Join)的方式来实现关联查询的,就是要通过两层循环,用第一张表做外循环,第二张表做内循环,外循环的每一条记录跟内循环中的记录作比较,符合条件的就输出。
JOIN
会增加查询的复杂性,可能导致性能下降,特别是在数据量大时。JOIN
查询会使 SQL 语句变得难以理解,导致维护成本增加。JOIN
会让代码更容易出错。JOIN
可能会导致数据库无法有效利用索引,影响查询的优化。JOIN
的字段没有适当的索引,查询性能会显著下降。JOIN
可能导致更长时间的行锁或表锁,从而增加锁竞争的可能性,影响并发性能。JOIN
查询可能掩盖数据问题或不一致性,使得调试较为困难。JOIN
查询中返回的数据符合业务逻辑和数据完整性要求。那应该怎么写?
JOIN
的需要。UNION和UNION ALL是在SQL中用于合并查询结果集的操作符,它们之间存在以下区别:
总结来说:在使用时,可以根据具体的需求来选择合适的操作符。如果需要去除重复的行,可以使用UNION;如果不需要去重,或者对性能要求较高,可以使用UNION ALL。需要注意的是,使用UNION或UNION ALL时,要求被合并的查询结果的列数和列类型保持一致。
WHERE 1=1 表达式的值始终为 TRUE,因此它不会对查询结果产生任何实际的限制或筛选作用。它的主要作用是为条件语句提供一个基础条件,方便在构建动态SQL时,后续的查询条件可以更加灵活地拼接。
对于性能而言,WHERE 1=1 表达式并不会造成明显的性能损失。数据库优化器会意识到 1=1 永远为 TRUE,因此它不会对查询的执行计划产生任何实际影响。WHERE 1=1 在执行时不会进行额外的计算,因为它本质上是一个常量布尔值。
和
LIMIT 10 的执行速度是否相同?速度差很多,limit 10 快很多!
原因如下:
通常面对 LIMIT 100000000,10 这种大分页的情况,可以先使用条件过滤掉,比如使用主键 ID 来进行范围过滤,然后再 limit 10。
排序过程中,如果排序字段命中索引,则利用索引排序。反之,使用文件排序。
使用索引排序:当ORDER BY子句中的列恰好有对应的索引时,MySQL可以直接利用索引来完成排序操作,这是最高效的排序方式。索引本身是有序的,所以MySQL只需要按照索引的顺序扫描即可得到排序后的结果。
文件排序(filesort):当无法使用索引进行排序时,MySQL会使用文件排序。
具体的排序过程如下:
需要注意的是,ORDER BY的使用可能会对查询性能产生显著影响。我们可以通过以下方式优化排序操作:
总的来说,MVSQL的排序实现既考虑了效率(通过利用索引),又保证了在没有合适索引的情况下也能完成排序(通过文件排序)。理解这些原理对于优化数据库查询性能至关重要,
双路排序
有一个叫 max length for_sort cata参数,默认是4096字节,如果 select列的数据长度超过它,则 MySQL采用row id排序,即把 row id(有主键就是主键)+排序字段放置到 sort bufer 中排序
比如现在要执行: select a,b,c from t1 where a='seven'order by b;
假设select 列的数据长度超过了 max_length_for_sort_data,为了节省排序占用的空间,此时 sort bufer 只会有放置 id 和b 来排序。
排序后,再通过id 回表查询得到 a、b、c,最终将最后的结果集返回给客户端。所以排序需要多个回表的过程,等于需要两次查询,也叫双路排序(Two-Pass Sort)。
单路排序
假设 select 列的数据没有超过 max length for_sortdata,则可以进行单路排序(Singile-Pass Sort),就是将select 的字段都放置到 sort buffer 中
排序后直接得到结果集,返回给客户端即可,相比双路排序它减少了回表的动作,因此效率更高
开始 MySQL 只有双路排序,后续优化推出了单路排序。
磁盘文件临时排序
如果查询的数据超过 sort_bufer,说明内存放不下了,因此需要利用磁盘文件进行外部排序,一般会使用归并排序,简单理解就是将数据分为很多份文件,单独对文件排序,之后再合并成一个有序的大文件。利用磁盘排序效率会更低,针对一些情况可以调大sort buffer size,避免磁盘临时文件排序,
本文来自在线网站:seven的菜鸟成长之路,作者:seven,转载请注明原文链接:www.seven97.top
参与评论
手机查看
返回顶部