两表优化
左连接
LEFT JOIN 条件用于确定如何从右表搜索行,左边一定都有
所有右边是关键点一定要建索引
左连接 加右表关联字段加索引 右连接 加右边
select * from class LEFT JOIN book ON class.card=book.card
三表优化
join 语句的优化、
尽可能减少Join语句中的NestedLoop的循环总次数:“永远用小结果集驱动大的结果集”
优先优化嵌套循环的内层循环
sql语句优化注意事项
不在索引列上做任何操作
存储引擎不能使用索引中范围条件右边的列
(age 只给了一个范围)
select * from staffs where name=”tom” and age>25 and pos=”manager”
最佳做前缀法则
如果索引了多列,查询从索引最左前列的开始并且不跳过索引中间的列
(带头大哥不能死 中间兄弟不能断)
尽量使用覆盖索引(只访问索引的查询(索引列和查询一致)),减少使用select *
select name,age,pos from staff name=”tom” and age=25 and pos=”manager” 索引(nameAgePos)
mysql 使用 不等于 != <> 无法使用索引 会导致全表扫描
is null is not null 也无法使用索引(字段值尽量避免null)
like 以通配符开头(’%abc…’)mysql索引失效会变成全表扫描
百分号加在右边 避免索引失效
问题:解决 like %abc% 使用时,索引不被使用?
覆盖索引来解决
create intex inx_user_nameAge on user(name,age)
select name,age from user where name like ‘%aaa%’
字符串不加单引号 索引失效(开发中)
varchar 类型一定要加单引号
select * from staff where age=2000
少用or 索引会失效
优化口诀
全值匹配我最爱 最左前缀要遵循
带头大哥不能死 中间兄弟不能断
索引列上少计算 范围之后全失效
LIKE百分写最右 覆盖索引不写星
不等空值还有or 索引失效要少用
VAR引号不可丢 SQL高级也不难
小表驱动大表
小的数据集驱动大的数据集
select * from A where id in(select id from B)
等价于
for select id from B
for select * from A where A.id=B.id
当B表的数据集必须小于A表的数据集时,用in优于exists
当A表的数据集小于B表的数据集时,用exists由于in
select * from A where exists (select 1 from B where b.id=a.id)