OR优化
在Innodb引擎下or无法使用组合索引,比如:
select id,product_name from orders where mobile_no = '13421800407' or user_id = 100;
OR无法命中mobileno + userid的组合索引,可采用union,如下所示:
(select id,product_name from orders where mobile_no = '13421800407') union(select id,product_name from orders where user_id = 100);
此时id和product_name字段都有索引,查询才最高效。
IN优化
- IN适合主表大子表小,EXIST适合主表小子表大。由于查询优化器的不断升级,很多场景这两者性能差不多一样了。
- 尝试改为join查询,举例如下:
select id from orders where user_id in (select id from user where level = 'VIP');
采用JOIN如下所示:
select o.id from orders o left join user u on o.user_id = u.id where u.level = 'VIP';
不做列运算
通常在查询条件列运算会导致索引失效,如下所示:查询当日订单
select id from order where date_format(create_time,'%Y-%m-%d') = '2019-07-01';
date_format函数会导致这个查询无法使用索引,改写后:
select id from order where create_time between '2019-07-01 00:00:00' and '2019-07-01 23:59:59';
避免Select all
如果不查询表中所有的列,避免使用 SELECT *
,它会进行全表扫描,不能有效利用索引。
Like优化
like用于模糊查询,举个例子(field已建立索引):
SELECT column FROM table WHERE field like '%keyword%';
这个查询未命中索引,换成下面的写法:
SELECT column FROM table WHERE field like 'keyword%';
去除了前面的%查询将会命中索引,但是产品经理一定要前后模糊匹配呢?全文索引fulltext可以尝试一下,但Elasticsearch才是终极武器。
Join优化
join的实现是采用Nested Loop Join算法,就是通过驱动表的结果集作为基础数据,通过该结数据作为过滤条件到下一个表中循环查询数据,然后合并结果。如果有多个join,则将前面的结果集作为循环数据,再次到后一个表中查询数据。
- 驱动表和被驱动表尽可能增加查询条件,满足ON的条件而少用Where,用小结果集驱动大结果集。
- 被驱动表的join字段上加上索引,无法建立索引的时候,设置足够的Join Buffer Size。
- 禁止join连接三个以上的表,尝试增加冗余字段。
Limit优化
limit用于分页查询时越往后翻性能越差,解决的原则:缩小扫描范围 ,如下所示:
select * from orders order by id desc limit 100000,10 耗时0.4秒select * from orders order by id desc limit 1000000,10耗时5.2秒
先筛选出ID缩小查询范围,写法如下:
select * from orders where id > (select id from orders order by id desc limit 1000000, 1) order by id desc limit 0,10耗时0.5秒
如果查询条件仅有主键ID,写法如下:
select id from orders where id between 1000000 and 1000010 order by id desc耗时0.3秒
如果以上方案依然很慢呢?只好用游标了,感兴趣的朋友阅读JDBC使用游标实现分页查询的方法
其他数据库
作为一名后端开发人员,务必精通作为存储核心的MySQL或SQL Server,也要积极关注NoSQL数据库,他们已经足够成熟并被广泛采用,能解决特定场景下的性能瓶颈。
分类 | 数据库 | 特性 |
键值型 | Memcache | 用于内容缓存,大量数据的高访问负载 |
键值型 | Redis | 用于内容缓存,比Memcache支持更多的数据类型,并能持久化数据 |
列式存储 | HBase | Hadoop体系的核心数据库,海量结构化数据存储,大数据必备。 |
文档型 | MongoDb | 知名文档型数据库,也可以用于缓存 |
文档型 | CouchDB | Apache的开源项目,专注于易用性,支持REST API |
文档型 | SequoiaDB | 国内知名文档型数据库 |
图形 | Neo4J | 用于社交网络构建关系图谱,推荐系统等 |