一、全表扫描
在这些where子句中,即使某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用全表扫描,这就造成了响应速度的极大降低。
- IS NULL 与 IS NOT NULL
任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。
设置默认值为0或者’ ‘
(一) 使用查询缓存优化查询
这里最主要的问题是,对于我们程序员来说,这个事情是很容易被忽略的。因为我们某些查询语句会让MySQL不使用缓存,示例如下:
1:SELECT username FROM user WHERE signup_date >= CURDATE()
2:SELECT username FROM user WHERE signup_date >= ‘2014-06-24‘
上面两条SQL语句的差别就是 CURDATE() ,MySQL的查询缓存对这个函数不起作用。所以,像 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的。所以,你所需要的就是用一个变量来代替MySQL的函数,从而开启缓存。
(二) 使用EXPLAIN关键字检测查询
使用EXPLAIN关键字可以使我们知道MySQL是如何处理SQL语句的,这样可以帮助我们分析我们的查询语句或是表结构的性能瓶颈;EXPLAIN的查询结果还会告诉我们索引主键是如何被利用的,数据表是如何被被搜索或排序的。
(三)当只要一行数据时使用LIMIT 1
(四)为搜索字段建立索引
普通索引INDEX:适用于name、email等一般属性
唯一索引UNIQUE:与普通索引类似,不同的是唯一索引要求索引字段值在表中是唯一的,这一点和主键索引类似,但是不同的是,唯一索引允许有空值。唯一索引一般适用于身份证号码、用户账号等不允许有重复的属性字段上。
主键索引:其实就是主键,一般在建表时就指定了,不需要额外添加。
全文检索:只适用于VARCHAR和Text类型的字段。
注意:全文索引和普通索引是有很大区别的,如果建立的是普通索引,一般会使用like进行模糊查询,只会对查询内容前一部分有效,即只对前面不使用通配符的查询有效,如果前后都有通配符,普通索引将不会起作用。对于全文索引而言在查询时有自己独特的匹配方式,例如我们在对一篇文章的标题和内容进行全文索引时:
ALTER TABLE article ADD FULLTEXT (‘title’, ‘content’); 在进行检索时就需要使用如下的语法进行检索:
SELECT * FROM article WHERE MATCH(‘title’, ‘content’) AGAINST (‘查询字符串’);
在使用全文检索时的注意事项:
MySql自带的全文索引只能用于数据库引擎为MYISAM的数据表,如果是其他数据引擎,则全文索引不会生效。此外,MySql自带的全文索引只能对英文进行全文检索,目前无法对中文进行全文检索。如果需要对包含中文在内的文本数据进行全文检索,我们需要采用Sphinx(斯芬克斯)/Coreseek技术来处理中文。另外使用MySql自带的全文索引时,如果查询字符串的长度过短将无法得到期望的搜索结果。MySql全文索引所能找到的词默认最小长度为4个字符。另外,如果查询的字符串包含停止词,那么该停止词将会被忽略。
二、搜索引擎的选择
innerdb 事务优先,适用于多并发(行锁)
myisam 性能优先(表锁)
解析过程:from,on,join,where,group by,having,select,order by,limit
dml需要commit
ddl表级操作自动提交
type类型:system,const,eq_ref,ref,range,index,all
using filesort 额外的一次排序或查询,orderby常见,where和orderby涉及字段都要看。
using temporary 生成临时表,groupby常见
索引覆盖:查询数据全在索引中,不会回表查询
复合索引跨列引发回表查询。
小表驱动大表,
索引失效:
- 复合索引没有全用
- 不要在索引列做计算操作
- 不使用<>,!=,is null,is not null,or
- like不要以%开头
- 类型转换
主查询数量大用in
子查询数数量大用exist