// todomysql
InnoDB:支持事物、在线热备份、行锁
MyISAM:支持全文索引、地理空间索引算法
索引是帮助MySQL高效获取数据的数据结构,因此索引本质上是一种数据结构
create indexsql
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类型的列,必须使用前缀索引,只索引开始的部分字符
多列索引
在须要使用多个列做为条件查询时,使用多列索引比使用单列索引性能要好
索引列的顺序
在写查询语句时,将选择性强的列放在前面
left join是由左边决定的,左边必定都有,因此右边是咱们的关键点,创建索引要建右边的。固然若是索引在左边,能够用右链接。
尽量减小Join语句中的NestedLoop的循环次数:“永远用小结果集驱动大的结果集”
where条件的列=
的判断放在比较运算符>
、<
等的左边,放在比较运算符右边的索引会失效
好比:
select * from user where username="saboran" and age > 18 and mobile = "18862612345"
其中username、age、mobile都有索引,可是只有username和age的索引会生效,mobile索引用不到
select *
操做,用须要的字段代替*
!=
或者<>
的时候没法使用索引,会致使全表扫描like 以通配符开头,mysql索引会失效变成全表扫描
因此最好用右边通配符匹配like 'tssk%'
若是要使用两边通配符匹配,则将like条件放在最后一个
好比:
select age from users where a = 3 and b = 4 and c like "%abcd%";
这样a、b、c都有索引的话,a、b用的上,c用不上
用来分析SQL语句,分析结果中比较重要的字段有:
慢查询主要是由于访问了过多数据,除了访问过多行以外,也包括访问了过多列。最好不要使用select *
语句,要根据须要选择查询的列
最好使用limit
语句取出想要的那些行,还能够创建索引来减小条件语句的全表扫描
ABS(x) // 返回x的绝对值
select abs(age) from users limit 1; -- 18
BIN(x) // 返回x的二进制数
select bin(age) from users limit 1; -- 10010
CEILING(x) // 返回大于x的最小整数值
SELECT CEILING (19.1) ; -- 20
FLOOR(x) // 返回小于x的最大值
SELECT floor (19.1) ; -- 19
RAND() // 返回0到1的随机数
SELECT rand() ; -- 0.8320153586864615 随机数
ROUND(x,y) // 返回参数x的四舍五入的y位小数值
SELECT ROUND(100.123456,3); -- 100.123
AVG(col) // 返回指定列的平均数
select avg(age) from users ; -- 14.0000
COUNT(col) // 返回指定列中非null值的个数
SELECT count(id) from users ; -- 2
MIN(col) // 返回指定列的最小值
select min(age) from users ; -- 10
MAX(colcol) // 返回指定列的最大值
select max(age) from users ; -- 18
SUM(col) // 返回指定列全部值的和
select sum(age) from users ; -- 28
GROUP_CONCAT(col) // 返回由属于一组的列值链接组合而成的结果
select GROUP_CONCAT(age) from users ; -- 18,20
CONCAT(s1,s2,s3,sn) // 将s1,s2,s3,sn链接为字符串
select CONCAT(id,age,name) from users limit 1; -- 118安小下
CONCAT_WS('|') // 将s1,s2,s3,sn链接为字符串,并使用|
分隔,|
能够替换为任意分隔符
SELECT CONCAT_WS('|',id,name,age) from users limit 1; -- 1|安小下|18
CURDATE()/CURRENT_DATE() // 返回当前日期
SELECT CURRENT_DATE(); -- 2018-03-08
CURTIME()/CURRENT_TIME() // 返回当前时间
SELECT CURRENT_TIME(); -- 08:54:15
DATE_FORMAT(date,fmt) // 按照fmt格式,格式化date
SELECT DATE_FORMAT(CURRENT_DATE(),'%Y/%m/%d'); -- 2018/03/08
DAYOFWEEK(date) // 返回date为一周以内的第几天,从0开始,0表明第一天
SELECT DAYOFWEEK(CURRENT_DATE()); -- 5
DAYOFMONTH(date) // 返回date为一月以内的第几天
SELECT DAYOFMONTH(CURRENT_DATE()); -- 8
DAYOFYEAR(date) // 返回date为一年以内的第几天
SELECT DAYOFYEAR(CURRENT_DATE()); -- 67
DAYNAME(date) // 返回date的星期名
SELECT DAYNAME(CURRENT_DATE()); -- Thursday
FROM_UNIXTIME(timestimps,fmt) // 时间戳转成fmt格式的字符串时间
SELECT FROM_UNIXTIME(1520500384,"%Y/%m/%d"); -- 2018/03/08
HOUR(time) // 返回time的小时值(0-23)
SELECT HOUR('20:10'); -- 20
MINUTE(time) // 返回time的分钟值(0-59)
SELECT HOUR('20:10'); -- 10
MONTH(date) // 返回date的月份值(1-12)
SELECT MONTH(CURRENT_DATE()); -- 3
MONTHNAME(date) // 返回date的月份名
SELECT MONTHNAME(CURRENT_DATE()); -- March
NOW() // 获取当前日期和时间
SELECT NOW(); -- 2018-03-08 09:26:55
WEEK(date) // 返回日期date为一年中的第几周
SELECT WEEK(CURDATE()); -- 9
YEAR(date) // 返回日期date的年份
SELECT YEAR(CURDATE()); -- 2018
// todo
单独的distinct只能放在开头
-- 会报错 select id,DISTINCT(name) from test; -- 不会报错 select DISTINCT(name) from test;