怎么提高数据库查询效率

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么提高数据库查询效率相关的知识,希望对你有一定的参考价值。

提高查询效率首先要想到的就是加索引,那什么是索引呢?
mysql索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。
打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。
索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。
上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
建立索引会占用磁盘空间的索引文件。
如何使用索引呢?
首先索引有窄索引和宽索引两个概念,窄索引是指索引的列数为1~2,宽索引就是说索引的列数大于2。
因为窄索引的效率要高于宽索引,所以能用窄索引就不要使用宽索引。
那么对单字段索引和复合索引应该如何使用?
目录
单字段索引的情况:
复合索引的优势:
两者的比较:
单字段索引的情况:
1.表的主键,外键必须有索引
2.数据量超过300的表应该有索引
3.经常与其他表进行连接的表,在连接字段上应该建立索引
4.经常出现在where字句中的字段,特点是大表的字段,应该建立索引
5.索引应该建在选择性高的字段上
6.索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建立索引
7.尽量用单字段索引代替复合索引,复合索引的建立需要仔细的斟酌
复合索引的优势:
1.单字段索引很少甚至没有
2.复合索引的几个字段经常同时以AND的方式出现在where语句
当where语句中的条件是OR时,索引不起作用。
两者的比较:
以一个sql语句来举例:SELECT * FROM STUDENT WHERE SEX="男" AND SAGE=18;
若在sex 和 sage 两个字段分别创建了单字段索引,mysql查询每次只能使用一个索引,虽然对于未添加索引时使用全盘扫描,我们的效率提升了很多,但如果在sex 和 sage两个字段添加复合索引,效率会跟高,如: 创建(sex, age,teacher)的复合索引,那么其实相当于创建了(area,age,teacher)、(area,age)、(area)三个索引,这被称为最佳左前缀特性。
那对于两者优缺点的比较:
1.对于具有2个用and连接条件的语句,且2个列之间的关联度较低的情况下,复合索引有一定优势。
2.对于具有2个用and连接条件的语句,且2个列之间的关联度较高的情况下,复合索引有很大优势。
3.对于具有2个用or连接条件的语句,单索引有一定优势,因为这种情况下复合索引将会导致全表扫描,而前者可以用到indexmerge的优化。
以上就是如何提高查询效率的全部内容,如果有帮助到你的话记得点个关注哟
参考技术A 在使用数据库查询的时候注意以下几点,可以提高查询效率:

1、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引;

2、注意UNion和UNion all 的区别。UNION all好;

3、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的;

4、查询时不要返回不需要的行、列。

记录一个sql优化后大大提高查询效率的情形

众所周知,sql写得怎么样,对于查询效率的影响是颇大的。下面看一个比较普通的查询:

假设一张表有event_date和event_time2个字段分别表示日期和时间,现在直接给你一个时间字符串,这个时间字符串是“日期+时间”的组合,现在需要按时间范围过滤出一部分数据。如果你不转弯的话,很有可能你会按照惯性思维使用concat(event_date, event_time)连接函数,如:

SELECT A, MAX(B) AS B,SUBSTR(CONCAT(event_date, event_time),1,12)AS tran_time 
       FROM tablename 
 WHERE SUBSTR(CONCAT(event_date, event_time),1,12) >= :start_time  
 AND SUBSTR(CONCAT(event_date, event_time),1,12) < :end_time  
     AND A = :A  	
        GROUP BY A,tran_time  
        ORDER BY A,tran_time ASC

start_time和end_time是传递过来的由“日期+时间”组合成的字符串。

这是比较容易想到的传统思维,但这种sql语句的查询效率老低了。差不多查一次需要4.5s+, 因为不仅仅需要用到max函数,还需按SUBSTR(CONCAT(event_date, event_time),1,12) 这个计算出来的字段group by,最主要的是在where语句里,对2个时间的字段需要进行多重函数运算后看看那些记录符合你所规定的时间范围~~ 这样,在不知不觉中,造成了全表扫描,效率极低,特别是在表中数据量比较大的时候。

我们已经知道,如果一张表是数据量比较大的表,并且一般都用与于查询时,索引的使用会给我们带来极大的性能优化。考虑到使用索引,我们应该尽量避免where语句里的字段不进行函数作用(因为即使你对where下的字段建立了索引,但如果你对他们进行了函数运算,索引是失效的),所以我们考虑把它们尽量独立开来。

基于上述思想,改正如下:

先对A, evnet_date和event_time三个字段建立索引。

SELECT A, MAX(B) AS B,SUBSTR(CONCAT(event_date, event_time),1,12)AS tran_time 
       FROM tablename  
 WHERE event_date >= :start_date AND event_time >= :start_time  
       AND event_date <= :end_date AND event_time < :end_time   
     AND A = :A  	
        GROUP BY A,tran_time  
        ORDER BY A,tran_time ASC

可以看出我们把event_date和event_time的起止时间都“拆”开来了,所以只需在传过来的起止时间字符串上截取响应的日期和时间字符串给sql语句即可。

测试检查发现,2句sql查询出的结果是一致的,说明他们是等效的。

改正之后,发现效率提升至0.05s左右,性能得到极大提升!!!

这句优化后的sql语句是突破了sql语句字段去适应外部传过来的时间字符串,而是从sql优化的角度看,让外部的条件去适应sql语句的查询,这种思想我之前很少有,也算是一种思维的突破了!

 

 

以上是关于怎么提高数据库查询效率的主要内容,如果未能解决你的问题,请参考以下文章

如何提高oracle模糊查询的性能?

[ElasticSearch] ElasticSearch在数十亿级别数据下,如何提高查询效率?

使用kettle向mysql插入数据~ 每秒10条...应该是mysql的问题。怎么能提高效率么~

提高mysql数据库查询效率

sql语句提高数据库查询效率

如何提高sql2000全文检索搜索效率