(8) SELECT(9) DISTINCT column,…
选择字段 、去重
(6) AGG_FUNC(column or expression),…
聚合函数
(1) FROM [left_table]
选择表
(3) JOIN
链接
(2) ON
链接条件
(4) WHERE
条件过滤
(5) GROUP BY
分组
(7) HAVING
分组过滤
(10) ORDER BY
排序
(11) LIMIT count OFFSET count;
分页
SELECT * FROM student
SELECT id,NAME FROM student
查询id为1或者薪水为3000的用户:
SELECT * FROM student WHERE id=1 OR salary=30000
(1)使用union all
SELECT * FROM student WHERE id=1
UNION ALL
SELECT * FROM student WHERE salary=30000
(2)分开两条sql写
SELECT * FROM student WHERE id=1
SELECT * FROM student WHERE salary=30000
`deptname` char(100) DEFAULT NULL COMMENT '部门名称'
`deptname` varchar(100) DEFAULT NULL COMMENT '部门名称'
SQL很灵活,一个需求可以很多实现,那哪个最优呢?SQL提供了explain关键字,它可以分析你的SQL执行计划,看它是否最佳。Explain主要看SQL是否使用了索引。
EXPLAIN
SELECT * FROM student WHERE id=1
性能排行:
System > const > eq_ref > ref > range > index > ALL
显示可能应用在这张表中的索引
真正使用的索引方式
提高查询速度的最简单最佳的方式
ALTER TABLE student ADD INDEX index_name (NAME)
模糊查询,程序员最喜欢的就是使用like,但是like很可能让你的索引失效
EXPLAIN
SELECT id,NAME FROM student WHERE NAME LIKE '%1'
EXPLAIN
SELECT id,NAME FROM student WHERE NAME LIKE '%1%'
EXPLAIN
SELECT id,NAME FROM student WHERE NAME LIKE '1%'
EXPLAIN
SELECT id,NAME FROM student WHERE NAME=1 OR sex=1
EXPLAIN
SELECT id,NAME FROM student WHERE id=1
EXPLAIN
SELECT id,NAME FROM student WHERE id LIKE '%1'
#未使用索引
EXPLAIN
SELECT * FROM student WHERE NAME=123
#使用索引
EXPLAIN
SELECT * FROM student WHERE NAME='123'
为什么第一条语句未加单引号就不走索引了呢?这是因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为数值类型再做比较
如性别字段。因为SQL优化器是根据表中数据量来进行查询优化的,如果索引
列有大量重复数据,Mysql查询优化器推算发现不走索引的成本更低,很可能就放弃索引了。
数据中假定就一个男的记录
SELECT id,NAME FROM student WHERE sex='男'
SELECT id,NAME FROM student WHERE id=1 AND sex='男'
需要什么数据,就去查什么数据,避免返回不必要的数据,节省开销
业务需求:查询最近七天内新生儿(用学生表替代下)
1)、给birthday字段创建索引:
ALTER TABLE student ADD INDEX idx_birthday (birthday)
2)、当前时间加7天:
SELECT NOW()
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY)
3)、反例:
EXPLAIN
SELECT * FROM student
WHERE DATE_ADD(birthday,INTERVAL 7 DAY) >=NOW();
4)、正例:
EXPLAIN
SELECT * FROM student
WHERE birthday >= DATE_ADD(NOW(),INTERVAL 7 DAY);
5)、理由:
使用索引列上内置函数
索引失效:
EXPLAIN
SELECT * FROM student WHERE id+1-1=+1
EXPLAIN
SELECT * FROM student WHERE id=+1-1+1
EXPLAIN
SELECT * FROM student WHERE id=1
应尽量避免在where子句中使用!=或<>操作符,否则引擎将放弃使用索引而进行全表扫描。记住实现业务优先,实在没办法,就只能使用,并不是不能使用。如果不能使用,SQL也就无需支持了。
EXPLAIN
SELECT * FROM student WHERE salary!=3000
EXPLAIN
SELECT * FROM student WHERE salary<>3000
使用!=和<>很可能会让索引失效
# 索引失效
EXPLAIN
SELECT DISTINCT * FROM student
# 索引生效
EXPLAIN
SELECT DISTINCT id,NAME FROM student
# 索引生效
EXPLAIN
SELECT DISTINCT NAME FROM student
带distinct的语句占用cpu时间高于不带distinct的语句。因为当查询很多字段时,如果使用distinct,数据库引擎就会对数据进行比较,过滤掉重复数据,然而这个比较、过滤的过程会占用系统资源,如cpu时间
#修改表,增加age字段,类型int,非空,默认值0
ALTER TABLE student ADD age INT NOT NULL DEFAULT 0;
#修改表,增加age字段的索引,名称为idx_age
ALTER TABLE student ADD INDEX idx_age (age);
EXPLAIN
SELECT * FROM student WHERE age IS NOT NULL
EXPLAIN
SELECT * FROM student WHERE age>0