查看表定义:show create table users;
查看表的索引:show index from users;
你要获取第一个表的所有信息,你说全表扫描快呢还是索引扫描快呢?所以当你查找库(包括left join中的临时库)的所有信息时,数据库会选择最优方法——全表扫描!!!
/*s表dept_id、name,及d表的id_o均加了索引!!!*/
/*(只使用了d表的索引)导致只有s表内容全的,d表只现示s.name='zs'对应的值 */
EXPLAIN
select s.name,d.name from student s left join dept d on s.dept_id = d.id_o and s.name='zs'
/*(使用了双表的索引),很值得记住的写法left join on where!!!*/
EXPLAIN
select s.name,d.name from student s left join dept d on s.dept_id = d.id_o where s.name='zs'
对查询进行优化,应尽量避免全表扫描
1. 首先应考虑在 where 及 order by 涉及的列上建立索引,使用选择率高的字段建索引。
2. 不使用 != 或 <> 操作符ALL。
3. 不使用 is null 或 is not null ALL
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
4. 不使用 orALL
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
5. 如果like是以‘%’开始ALL
6. 不使用 in 和 not in ALL
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
7. 不在where进行函数运算 ALL
8. 不使用复合索引的第一部分(即最左前缀原则)ALL
9. 建议 exists 代替 in (注意两边表的数量多少)
EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS内部有一个子查询语句(SELECT ... FROM...), 我将其称为EXIST的内查询语句。
其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。
一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。
10. 索引并不是越多越好,可以提高select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引(B+Tree的insert导致树结构变化)