本文主要整理基础篇中的问题PS:文中整理的知识内容和资料均来自极客时间《SQL必知必会》专栏1.MySQL统计中行号、SELECTCOUNT(*)、SELECTCOUNT(1)和SELECTCOUNT(具体字段)的查询效率如何?在MySQLInnoDB存储引擎中,COUNT(*)和COUNT(1)都对所有结果执行COUNT。如果有WHERE子句,就是统计数据表中的数据行数。因此,COUNT(*)和COUNT(1)本质上没有区别。执行的复杂度为O(N),即全表扫描,使用循环+计数进行统计。在MySQLMyISAM存储引擎中,统计数据表的行数只需要O(1)的复杂度,因为每张MyISAM数据表都有一个存储row_count值的元信息,一致性是通过表级锁实现的.确保。因为InnoDB支持事务,使用行级锁和MVCC机制,所以不能像MyISAM那样只维护一个row_count变量。所以需要扫描全表,循环+计数完成统计。另外,在InnoDB引擎中,如果使用COUNT(*)和COUNT(1)统计数据行数,尽量使用二级索引。因为主键使用的索引是聚簇索引,所以聚簇索引包含的信息更多,明显大于二级索引(非聚簇索引)。对于COUNT(*)和COUNT(1),它们不需要查找具体的行,只统计行数,系统会自动使用占用空间少的二级索引进行统计。总结:1、列名为主键,count(列名)与count(1)和count(*)执行效率相同:因为explain中的type类型是index2,所以列名不是主键,并且列名还没有创建索引但是其他字段创建了索引:count(1)=count(*)>count(columnname);因为expalin中的类型typecount(1)和count(*)都是索引,count(列名)类型type是all3,列名不是主键,但是列名创建索引:count(1)=count(*)=count(列名);因为explain中的type类型是index4,如果表有多个列,没有主键,则count(1)=count(*)5.如果表只有一个字段,selectcount(*)和selectcount(1))与selectcount(columnname)具有相同的执行效率。2、在MySQL中,LIMIT关键字是最后执行的。如果确认只有一个结果集,为什么还需要加LIMIT1进行优化呢?如果可以确定只有一个结果集,那么在加上LIMIT1的时候,找到一个结果就不会再继续扫描,这样可以加快查询速度。如果数据表已经为字段建立了唯一索引,则可以通过索引进行查询。如果不扫描全表,则不需要加LIMIT1。3、在WHERE子句中加索引可以快速定位到数据,那么为什么要在ORDERBY字段中加索引呢?在MySQL中,支持两种排序方式,分别是FileSort和Index排序。在索引排序中,索引可以保证数据的顺序,不需要重新排序,效率更高。但是FileSort排序一般都是在内存中排序,比较占用CPU。如果待排序的结果很大,会出现临时文件I/O到磁盘进行排序,效率较低。因此,在使用ORDERBY子句时,应尽量使用Index排序,而不是FileSort排序。当然你可以使用explain查看执行计划,看优化器是否使用索引进行排序。4.ORDERBY是对组进行排序还是对组中的记录进行排序?ORDERBY是对记录进行排序。如果在ORDERBY之前使用GROUPBY,其实就是一种分组聚合方式。一组数据已经聚合成一条记录,在排序的时候,相当于对分好的组进行排序。
