sql语句优化
1、尽量不要使用select * ,需要哪些字段就拿哪些
2、Oracle和myslq中采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。
3、用EXISTS替代IN、用NOT EXISTS替代NOT IN。参考
(小表驱动大表: in后面跟的是小表,exists后面跟的是大表。简记:in小,exists大。)
4、索引使用,参考下面
5、开启慢查询日志检测慢查询
6、show processlist查看一直在频繁执行的语句, 对其进行优化
7、使用explain分析SQL.在 explain的帮助下,您就知道什么时候该给表添加索引,以使用索引来查找记录从而让select 运行更快。
8、通常对列进行计算都会使得索引失效, 所以不要在数据层处理, 最好在业务逻辑中编写计算, FROM_UNIX时间转化除外
9、join连接时, 注意大表和小表的问题, 驱动表应该是小表。
当进行多表连接查询时, [驱动表] 的定义为:
1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表]
2)未指定联接条件时,行数少的表为[驱动表](Important!)
忠告:如果你搞不清楚该让谁做驱动表、谁 join 谁,请让 MySQL 运行时自行判断
既然“未指定联接条件时,行数少的表为[驱动表]”了,而且你也对自己写出的复杂的 Nested Loop Join 不太有把握(如下面的实例所示),就别指定谁 left/right join 谁了,请交给 MySQL优化器 运行时决定吧。
索引相关优化
最基础:索引的使用,尽量能够做到一一对应每条数据表中的数据。
1、表的主键、外键必须有索引; (主键数据库会自动创建, 外键如果没声明不会)
2、数据量超过300的表应该有索引;
3、经常与其他表进行连接的表,在连接字段上应该建立索引;
4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
5、索引应该建在选择性高的字段上;
6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;
7、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:
A、正确选择复合索引中的主列字段,一般是选择性较好的字段;
B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?
单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;
C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
8、频繁进行数据操作的字段,不要建立索引, 这个的取舍一般靠意会,如果查询10次以上才更新一次我觉得还是可以建立的;
9、索引不会包含有NULL值的列,所以在数据库设计上不要让默认为null。 或者NULL必须时为了查询完整性不要包括NULL的字段,
一般
建议设置所有字段为not null,并设置默认值为' '(判断空字符用=''或者 <>''来进行处理,此处辟谣<>并不会使索引失效), NULL/null 是指没有值,而 ' ' 则表示值是存在的,只不过是个空值。
'IS NULL IS NOT NULL' 只针对可以为空的字段的判断, 并且(在可以为空字段上判断)会导致索引失效, 所以在一些关键字段上, 是万万不能加NULL判断的
而对于已经有 NOT NULL 修饰的字段来说,不要再使用 IS NULL 或者 IS NOT NULL 来作为查询条件,没有意义。
聚合函数,count(), min(), sum(), 将会忽略 NULL 值
要设置默认类型为'' , 不属于输入空格符, id相关可设置为0 (mysql自增id从1开始,所以不会产生影响)
10、什么样的字段不适合建索引?
一般来说,列的值唯一性太小(如性别,类型什么的),不适合建索引(怎样叫太小?一半说来,同值的数据超过表的百分之15,那就没必要建索引了)
太长的列,可以选择只建立部分索引,(如:只取前十位做索引)
非聚簇索引存储了对主键的引用,如果select字段不在非聚簇索引内,
就需要跳到主键索引(上图中从右边的索引树跳到左边的索引树),再获取select字段值
如果非聚簇索引值重复率高,那么查询时就会大量出现上图中从右边跳到左边的情况,导致整个流程很慢
11、多列查询该如何建索引?
一次查询只能用到一个索引
,
每个索引在数据库中都是一个索引树,其数据节点存储了指向实际
数据的指针,如果用一个索引来查询,其原理就是从索引树上去检索,
并获得这些指针,然后去取出数据,试想,如果你通过一个索引,得到过滤后的指针,这时,你的另一个条件索引如果再过滤一遍,
将得到2组指针的集合,如果这时候取交集,未必就很快,
因为如果每个集合都很大的话,取交集的时候,等于扫描2个集合,效率会很低,所以没法用2个索引。
所以 首先枪毙 a,b各建索引方案
a还是b? 谁的区分度更高(同值的最少),建谁!
当然,联合索引也是个不错的方案,ab,还是ba,则同上,区分度高者,在前
12、orderby 中的字段--一般是时间,
当order by 字段出现在where条件中时,才会利用索引而无需排序操作。其他情况,order by不会出现排序操作。
如果最终的结果集是以order by字段为条件筛选的,将order by字段加入索引,并放在索引中正确的位置,会有明显的性能提升。
,因为如果建立了索引, 查询是只需要对索引的前几个进行提取就行, 省略了sort操作
一般
如果只是需求最新数据放前面, 完全可以针对唯一自增id做排序, 这样就启用了主键索引来进行排序, 效率提升, 也不用对时间列再做索引
13、[重要]当大表关联小表时(数据量差异95%以上), 没必要在大表创建小表的索引。
其实or的效率为O(n),而in的效率为O(log2n)
https://blog.csdn.net/weixin_40609759/article/details/79998911
网友评论