一个任务是由很多子任务组成的,每个子任务都会消耗一定时间,如果优化查询,要么消去一些子任务,要么让子任务更快。
减少访问的行数。
在mysql服务器层是否在分析大量不必要的行。
通常在1:1到10:1之间,比如一个联级查询,要扫描多行才能返回一行。
mysql有很多访问方式可以查找并且返回一行结果。
这些方式可能需要访问很多行才能返回一行结果,也可以不需要访问。
explain的type列反应了访问类型:全表扫描,索引扫描,范围扫描,唯一索引扫描,常数引用等。
索引的功能就是让mysql以扫描最少的方式找到需要的记录。
eg.如果使用了索引,type=ref可能只需要访问10行数据,而如果不使用则需要使用全表的行数。
临时表的生命周期通常仅限于当前会话,因此在会话结束后会自动删除。
修改临时表不会影响原表。这是因为临时表在数据库中是独立存在的,具有自己的数据和结构,和原表没有直接关联。
分解联级查询的一个重要基础就是将复杂查询中的子查询结果缓存起来,然后在后续的查询中使用这些中间结果。
FROM:首先处理的是 FROM 子句,它决定了查询要处理的数据源。此步骤包括连接操作(JOIN)。
WHERE:接下来处理 WHERE 子句,用于过滤从 FROM 子句中选择的行。
GROUP BY:然后是 GROUP BY 子句,它将选择的行分组。
HAVING:接下来处理 HAVING 子句,对 GROUP BY 分组后的结果进行过滤。
SELECT:然后处理 SELECT 子句,确定要返回的列。
DISTINCT:如果使用了 DISTINCT 关键字,这一步会去除重复行。
ORDER BY:最后处理 ORDER BY 子句,对结果进行排序。
LIMIT:最后是 LIMIT 子句,用于限制返回的行数。
连接池-服务器-解析器-预处理器-优化器-存储引擎。
mysql认为每一个查询都是join查询。
两层for循环,拿每一个外层行去匹配内层所有行。
在mysql8以后不再使用,而是使用hash的join。
减少扫描次数:因为小表先扫描并连接,减少了大表的扫描和连接次数。
filesort:数据量小在内存,数据量大在磁盘。
需要创建临时表。
将所用到的列都放到内存,然后排序,返回需要返回的列。
select count(color = ‘blue’ or null) as blue,count(color = ‘red’ or null) as red from items;
当执行,order by id limit 10000,20这样的操作时,会访问10020行才返回20行。因为需要排序,会加载一个临时表。
这个语句主要的问题就是offset:10000
where id > offset的位置 limit 20
减少回表
SELECT *
FROM large_table
WHERE id IN (
SELECT id
FROM large_table
ORDER BY some_column
LIMIT 10000, 20
);