Mysql优化
1. Max函数优化
我前几天看了数据库的排行榜,mysql是第二,所以还是可以学一下mysql的优化。
这节视频讲的是给特殊需要用到的数据加上索引,会更很多。
如果使用max函数,会遍历全表,然后给表的字段加上索引之后,数据库会特殊处理其数据,这时的Max内的值 其实是一个索引,相当于是忽略了其它数据,而没有遍历全部的数据,这样以达到优化的效果。
create index index_name on payment(index_column);
explain select max(payment_date) from payment \G;
# 查看数据库对其的处理
2. 函数Count的优化
count好像并没有讲什么细的,只讲了count(*)包含null值,count(id)不包含null值。
3. 子查询的优化
这里子查询也没有讲到什么东西,就讲了一个distinct去除重复的值,然后就是将子查询转成关联查询。然后没了。
4. Group BY 优化
- Mysql中using的关键词的作用,也就是说要使用using 那么表a与表b必须要有相同的列。
- 在用joins进行多表联合查询时,我们通常使用ON来建立两个表的关系,其实还有一个更方便的关键字,那就是Using。
- 如果两个表的关联字段名是一样的,就可以使用Using来建立关系,简洁明了。
using的使用
需求:每个演员所参演影片的数量)影片表和演员表.
select * from a let join b using(a_id) group by xxx;
using(a_id) 相当于 on a.a_id = b.a_id
使用using代替了直接使用索引,所以using的字段还得是索引吧?
5. Limit 查询的优化
结论:扫描行数不变,执行的计划很固定,效率也很固定的。
注意事项:
- 主键要顺序排序并连续的,如果主键中间空缺了某一列,或者某几列,会出现列出数据不足5行的数据,如果不连续的情况,建立一个附加的列index_id列,保证这一列数据要自增的,并添加索引即可。
limit操作的时候使用order by 了,也需要使用 主键,或者索引
这让我反思一个问题:无论什么表都应该有一条自增的主键,然后查询的时候这便是可以提速的依据。
通过给limit加上条件,以达到限制的作用,这不是理所应当的吗?为什么会在优化里面出现。
6. 索引的优化
这里面学到了一个很有意思的点,PRIMARY KEY 本质是 UNIQUE,仅仅是其名字为PRIMARY KEY,因为一个表中不能两个同名的索引,所以只能有一个PRIMARY KEY。
使用索引的情况
- 表的主关键字
- 自动建立唯一索引
- 表的字段唯一约束
- 直接条件查询的字段(在SQL中用于条件约束的字段)
- 查询中与其它表关联的字段
- 查询中排序的字段(排序的字段如果通过索引去访问那将大大提高排序速度)
- 查询中统计或分组统计的字段
- 记录太少(如果一个表中只有几条记录,采用索引去访问记录的话,那首先需要访问索引表,再通过索引表访问数据表,一般索引表与数据表不在同一个数据块)
- 经常插入,删除,修改的表(对一些经常处理的业务表应在查询允许的情况下尽量减少索引)
- 数据重复且分布平均的表字段(假如一个表有10万行记录,有一个字段A只有T 和F 两种值,且每个值的分布概率大约为 50% ,那么对这种表A字段建索引一般不会提高数据库的查询速度)
- 经常和主字段一块查询的但字段索引值比较多的表字段
- 对千万级Mysql的数据库建立索引的事项及提高性能的手段。
如何选择合适的列建立索引
这个就是多个字段联合建成一个索引,但需要测其离散度,数量越大的,说明其离散度越大。
索引优化SQL的方法
说明:对于innodb来说,每一个索引后面,实际上都会包含主键,这时候我们建立联合索引,又人为的把主键包含进去,所以这个索引就是冗余索引
冗余索引并不会加大查询的速度。
索引维护的方法
在mysql中,目前只能通过慢查询配合pt-index-usage 工具来进行索引使用情况的分析
END 注意事项
设计索引可以提升速度,但需要注意几点:
- 创建索引
- 如果不加索引,每次查询都会进行一次全表扫描,如果一张表的数据量很大,符合条件的结果又很少,那么不加索引会引起致命的性能下降。
- 但也不要什么情况都加索引,性别可能只有两个值,建索引不仅没有什么优势,还会影响到更新速度,这被称为过度索引。
- 复合索引
- 比如: select * from user where area='beijing' and age=22
- 如果我们在area和age上分别创建单个索引,由于mysql查询每次只能使用一个索引,虽然比没有索引快很多了,但将 area和age两列创建复合索引,将会带来更高的效率。
- 如果我们创建了( area, age ,salary) 的复合索引,那么相当于创建了 (area,age,salary) ,(area, age) , (area) 三个索引,这被称为最佳左前缀特性。
- 因为此我们在创建复合索引的时应该将最常用作限制条件的列放在最左边,依次递减。
- 索引不会包含有NULL值的列
- 只要列中有NULL值 都将不会被包含在索引中,复合索引只要有一列含有NULL值,那么这一列对于此复合索引就是无效的,所以设计数据库时不要让默认值为NULL。
- 使用短索引
- 对字符串列进行索引,如果可能应该指定一个前缀长度。如果有一个CHAR(255) 的列,如果在前10个或20个字符内,多数值是唯一的,那么就不要对整个列进行索引,短索引不仅可以提高查询速度,还可以节省IO操作
- 排序的索引问题
- mysql查询只使用一个索引,因此如果where 子句中已经使用了索引的话,那么orderby 中的列是不会使用索引的,因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
- like 语句操作
- 一般情况下不鼓励使用like 操作。
- like '%xx%' 不会使用索引
- 'like 'aa%' 会使用索引
- 不要在列上进行运算
- select * from users where YEAR(adddate)
- 不使用NOT IN 操作
- NOT IN操作都不会使用索引将进行全表扫描,NOT IN 可以 NOT EXISTS 代替。