select count(*) FROM film WHERE> release_year不可能同时为2006和2007,因此有逻辑错误
正确的方式:
SELECT COUNT(release_year='2006' OR NULL) AS '2006年电影数量',COUNT(release_year='2007' OR NULL) AS '2007年电影数量' FROM film;
{
现在说说count(*)和count(id)的区别:
新建一张表:create table t(id int);
插入数据:insert into t values (1),(2),(null);
当我们使用命令:select count(*),count(id) from t;
显示出count(*)为3,而count(id)为2;
说明count(*)包含了null的,count(id)不包含值为null的
}
11.子查询的优化
*通常情况下,需要把子查询优化为join查询,但在优化时要注意关联键是否有一对多的关系,要注意重复数据。
*我们新建一张表t1
create table t1(tid int);
插入一条数据insert into t1 values(1);
进行子查询:select * from t where t.id in (select * from t1.tid from t1);
返回t表id在t1表中的数据
*优化成join的形式:
select t.id from t join t1 on t.id=t1.tid;
这两种形式返回的结果是一样的
*需要注意的是:
如果在t1表中,添加一条数据:insert into t1 values(1);
然后在分别执行这两种形式的查询:
发现使用select * from t where t.id in (select * from t1.tid from t1);查询出来的结果是一条数据。而select t.id from t join t1 on t.id=t1.tid;是两条数据,说明有重复数据,我们可以使用distinct去重
select distinct t.id from t join t1 on t.id=t1.tid;这样就返回一条记录了
12.优化group by查询
explain SELECT actor.first_name,actor.last_name,count(*) FROM sakila.film_actor INNER JOIN sakila.actor USING(actor_id) GROUP BY film_actor.actor_id;
{
using可用在join语句相同字段连接,起到和ON相同作用,inner join 和left join中都可以使用
示例:LEFT JOIN 正常写法:
SELECT t1.id,t2.name FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE ....
其实也可以这么写:
SELECT t1.id,t2.name FROM t1 LEFT JOIN t2 USING(id) WHERE ....
}
上面的explain执行结果,可以看到extra为Using temporary,Using filesort 用到了临时表,文件排序的方式对表进行了全表扫描.
我们应该避免这种方式。改写如下:
Explain SELECT actor.first_name,actor.last_name,c.cnt FROM sakila.actor INNER JOIN(SELECT actor_id,COUNT(*) AS cnt FROM sakila.film_actor GROUP BY actor_id) AS c USING(actor_id);
13.优化limit查询
*limit常用于分页处理,时常会伴随order by从句使用,因此大多时候会使用Filesorts,这样会造成大量的IO问题
SELECT film_id,description FROM sakila.film ORDER BY> *这个语句进行explain操作,发现会进行全表扫描,并且有文件排序的方式
*优化方式:
步骤1.使用有索引的列或主键进行Order By操作
SELECT film_id,description FROM sakila.film ORDER BY film_id LIMIT 50,5
使用这种方式可以得到相同的结果,但是explain执行计划却完全不同,type=index,rows=55
这种方式并不是最优的,比如将limit 50,5改为limit 500,5;rows=505,rows会随着limit而改变,如果有上万条数据,那么响应速度回变慢
步骤2.记录上次返回的主键,在下次查询时使用主键过滤
SELECT film_id,description FROM sakila.film WHERE film_id>55 and film_id