Mysql索引优化

2018-04-19  本文已影响35人  沧海一粟谦

存储引擎

InnoDB

MyISAM

InnoDB与MyISAM的比较

索引

索引是帮助MySQL高效获取数据的数据结构,所以索引本质上是一种数据结构

索引分类

索引的优点

索引的缺点

创建索引的两种方式

create index

CREATE INDEX index_name ON table_name (column_list)

alter table

ALTER TABLE `table_name` ADD INDEX index_name (column_list)

操作索引

以articles的type字段为例

-- 创建索引
CREATE INDEX idx_type ON articles (type);

-- 删除索引
drop index idx_type on articles

-- 查看索引
show index from articles

使用索引的时机

一般情况下,在where或join子句中出现的列需要添加索引。但是,因为MySQL只对<,<=,=,>,>=,between,in,以及某些时候的like才会使用索引(使用like时,以通配符%和_查询时,MySQL不会使用索引)

创建索引技巧

使用索引的注意事项

索引优化

在查询时,索引不能是表达式的一部分,也不能是函数的参数,否则无法使用索引

对于blob,text,varchar类型的列,必须使用前缀索引,只索引开始的部分字符

在需要使用多个列作为条件查询时,使用多列索引比使用单列索引性能要好

在写查询语句时,将选择性强的列放在前面

join语句的优化

left join是由左边决定的,左边一定都有,所以右边是我们的关键点,建立索引要建右边的。当然如果索引在左边,可以用右连接。
尽可能减少Join语句中的NestedLoop的循环次数:“永远用小结果集驱动大的结果集”

避免索引失效

select * from user where username="saboran" and age > 18 and mobile = "18862612345"

其中username、age、mobile都有索引,但是只有username和age的索引会生效,mobile索引用不到

select age from users where a = 3 and b = 4 and c like "%abcd%";

这样a、b、c都有索引的话,a、b用的上,c用不上

一般性建议

查询性能优化


Explain

用来分析SQL语句,分析结果中比较重要的字段有:

减少返回的列

慢查询主要是因为访问了过多数据,除了访问过多行之外,也包括访问了过多列。最好不要使用select * 语句,要根据需要选择查询的列

减少查询的行

最好使用limit语句取出想要的那些行,还可以建立索引来减少条件语句的全表扫描

常用函数


数学函数

select abs(age) from users limit 1; -- 18
 select bin(age) from users limit 1; -- 10010
SELECT CEILING (19.1) ; -- 20
SELECT floor (19.1) ; -- 19
SELECT rand() ; -- 0.8320153586864615 随机数
SELECT ROUND(100.123456,3); -- 100.123

聚合函数(常用与group by从句的select查询中)

select avg(age) from users ; -- 14.0000\
SELECT count(id) from users ; -- 2
select min(age) from users ; -- 10
select max(age) from users ; -- 18
select sum(age) from users ; -- 28
select GROUP_CONCAT(age) from users ; -- 18,20

字符串函数

select CONCAT(id,age,name) from users limit 1; -- 118安小下
SELECT CONCAT_WS('|',id,name,age) from users limit 1; -- 1|安小下|18

日期和时间函数

SELECT CURRENT_DATE(); -- 2018-03-08
SELECT CURRENT_TIME(); -- 08:54:15
SELECT DATE_FORMAT(CURRENT_DATE(),'%Y/%m/%d'); -- 2018/03/08
SELECT DAYOFWEEK(CURRENT_DATE()); -- 5
SELECT DAYOFMONTH(CURRENT_DATE()); -- 8
SELECT DAYOFYEAR(CURRENT_DATE()); -- 67
SELECT DAYNAME(CURRENT_DATE()); -- Thursday
SELECT FROM_UNIXTIME(1520500384,"%Y/%m/%d"); -- 2018/03/08
SELECT HOUR('20:10'); -- 20
SELECT HOUR('20:10'); -- 10
SELECT MONTH(CURRENT_DATE()); -- 3
SELECT MONTHNAME(CURRENT_DATE()); -- March
SELECT NOW(); -- 2018-03-08 09:26:55
SELECT WEEK(CURDATE()); -- 9
SELECT YEAR(CURDATE()); -- 2018

加密函数

格式化函数

Distinct去重

单独的distinct只能放在开头

-- 会报错
select id,DISTINCT(name) from test;

-- 不会报错
select DISTINCT(name) from test;

转自:https://segmentfault.com/a/1190000013562810

上一篇 下一篇

猜你喜欢

热点阅读