聊聊数据库~4.SQL优化篇 - 鲲逸鹏 - 博客园 (cnblogs.com)
大方向:减少冗余索引,避免重复(无用)索引
数值 > 日期 > char > varchar > text、blob
crc32
(用bigint存储)索引空间就会小很多而且可以避免全表扫描select crc32('http://www.baidu.com/shop/1.html');
CRC32碰撞后的解决方案
)
select xxx from urls where crc_url=563216577 and url='url地址'
PS:需要关注的技术点:crc32
项目里面使用最多的是组合索引,这边先以组合索引为例:
-- 覆盖索引:仅仅查找索引就能找到所需要的数据
-- 查询的时候从最左边的列开始,并且不跳过中间的列,一直到最后
容易导致全表扫描,这时候利用覆盖索引可以简单优化
!=
、is not null
、is null
、not in
、in
、like
慎用like
案例:尽量使用xxx%
的方式来全文搜索,能和覆盖索引联合使用更好.
在like 索引上限定索引长度
6.查询语句优化:
使用union all 替代 or, in
不要count可空列
count优化案例:(有时候拆分查询会更快)
-- 需要统计id>10000的数据总量(实际中可能会根据时间来统计) explain select count(*) as count from userinfo where id > 10000; -- 2s -- 分解成用总数-小数据统计 ==> 1s explain select (select count(*) from userinfo) - (select count(*) from userinfo where id <= 10000) as count;
7. group by和order by的列尽量相同,这样可以避免filesort
-- 用exists代替in?MySQL查询优化器针对in做了优化(改成了exists,当users表越大查询速度越慢) explain select * from students where name in (select username from users where id < 7); -- ==> 等同于: explain select * from students where exists(select username from users where username = students.name and users.id < 7); -- 真正改进==>用连接查询代替子查询 explain select students.* from students inner join users on users.username = students.name and users.id < 7; -- 等效写法:这个tmp是临时表,是没有索引的,如果需要排序可以在()里面先排完序 explain select students.* from students inner join (select username from users where id < 7) as tmp on students.name = tmp.username;
很多人喜欢把where条件的常用列上都加上索引,但是遗憾的事情是:独立的索引只能同时用上一个
根据测试得知,一次只能使用1个索引。索引优先级:主键 > 唯一 > 组合 > 普通
组合索引