【MySQL】查询语句优化 𠔻

原文:
http://blog.gqylpy.com/gqy/389

???????MySQL的性能优化包罗甚广:索引优化、查询优化、查询缓存、服务器设置优化、操作系统及硬件优化、应用层优化(web服务器、缓存)等等。本文提到的优化技巧更适用于开发人员,都是从网络上收集和自己整理的,主要是查询语句上面的优化,其它层面的优化技巧在此不做记录。

整理如下

  1. 合理创建索引
  2. count 的优化
  3. 避免使用不兼容的数据类型
  4. 索引字段上进行运算会使索引失效
  5. 尽量避免使用 !=、is null、is not null、in、not in 这样的操作符
  6. 尽量使用数字型字段
  7. 合理使用 exists、not exists 子句
  8. 能够用 between 的就不要用 in
  9. 能够用 distinct 的就不要用 group by
  10. 尽量不要使用 select info 语句,它会导致表锁,阻止其它用户访问该表
  11. 必要时强制查询优化器使用某个索引
  12. 消除对大型表行数据的顺序存取
  13. 程序中如果需要一次性对同一个表插入多条数据,应写成一条语句

查询的开销指标

  • 执行时间
  • 检查的行数
  • 返回的行数

建立索引的几个准则

  1. 合理的建立索引能够加快数据读取效率,不合理的建立索引反而会拖慢数据的响应速度。
  2. 索引越多,更新数据的速度越慢。
  3. 尽量在采用 MyISAM 作为存储引擎的时候使用索引(因为MySQL以Btree存储索引),而不是 InnoDB 。但 MyISAM 不支持 Transcation。
  4. 当你的程序和数据结构/SQL语句已经优化到无法优化的程度,而程序的瓶颈并不能顺利解决,那就应该考虑使用诸如 memcached 这样的分布式缓存系统了。
  5. 习惯或强迫自己用 EXPLAIN 来分析你得SQL语句性能。

count的优化

比如,计算id大于5的城市,如下两种写法:

  1. seleft count(*) from world.city where id > 5;
  2. select (select count(*) from world.city) - count(*) from world.city where id <= 5;

???????当行数超过11时,1. 语句比 2. 语句扫描的行数要多,2. 语句只扫描6行,在此情况下,2. 语句比 1. 语句更有效率。当没有 where 语句的时候直接 select count(*) from world.city ,这样会更快,因为MySQL总是知道表的行数。

避免使用不兼容的数据类型...

例如 float和int、char和varchar、binary和varbinary 是不兼容的。 数据类型的不兼容可能会使优化器无法执行一些本来可以进行的优化操作。

  • 在程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数;
  • 通过搜索参数,尽量减少对表的访问次数,最小化结果集,从而减轻网络负担;
  • 能够分开的操作尽量分开处理,提高每次的响应速度;
  • 在数据库窗口使用SQL时,尽量把使用的索引放在选择的首列;
  • 算法的结构尽量简单;
  • 在查询时,不要过多地使用统配符,例如 select * from table,要用到哪个字段,就写哪个字;
  • 在可能的情况下尽量限制结果集行数,因为在某些情况下,用户是不需要那么多数据的;
  • 不要在应用中使用数据库游标,虽然游标是非常有用的工具,但是比使用常规的、面向集的SQL语句需要更大的开销;
  • 按照特定顺序提取数据的查找。

索引字段上进行运算会使索引失效

尽量避免在 where 子句中对字段进行函数或表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:select field from table where field / 2 = 10 应改为:select field from table where where field = 10 * 2 。

尽量避免使用 !=、<>、is null、is not null、in、not in 等这样的操作符

????????因为这会使系统无法使用索引,而只能直接搜索表中的数据,例如:select field from table where field != ‘xx%‘。优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行,在 in 语句中能用 exists 语句代替的就是 exists 。

尽量使用数字型字段

????????一部分开发人员和数据库管理人员喜欢把包含数值信息的字段设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中的每一个字符,而数字型只需要比较一次就够了。

合理使用exists、not exists子句

  1. select sum(t1.f1) from t1 where (select count(*) from t2 where t2.f2 = t1.f2 > 0);
  2. select sum(t1.f1) from t1 where exists(select * from t2 where t2.f2 = t1.f2);

????????两者产生的效果是相同的,但是后者的效率显然要高于前者,因为后者不会产生大量锁定的表扫描或是索引扫描。如果你想校验表中是否存在某条记录,不要使用 count(*) ,那样效率会很低,而且浪费服务器资源。可以用 exists 代替。如:if (select count(*) from t where f = ‘x‘); 可以写成:if exists (select * from t where f = ‘x‘); 。

必要时强制查询器使用某个索引

????????例如:select * from table where nextprocess = 1 and processid in (8, 32, 48);,应改为:select * from table (index = ix_processid) where nextprocess = 1 and processid in (8, 32, 45);,此时查询优化器将会强制利用索引ix_processid执行查询。

原文:
http://blog.gqylpy.com/gqy/389

原文地址:https://www.cnblogs.com/mypath1/p/11405812.html

时间: 2024-10-23 04:48:16

【MySQL】查询语句优化 𠔻的相关文章

MySQL 查询语句优化思路

query 语句的优化思路和原则主要提现在以下几个方面:1. 优化更需要优化的Query:2. 定位优化对象的性能瓶颈:3. 明确的优化目标:4. 从 Explain 入手:5. 多使用profile6. 永远用小结果集驱动大的结果集:7. 尽可能在索引中完成排序:8. 只取出自己需要的Columns:9. 仅仅使用最有效的过滤条件:10. 尽可能避免复杂的Join和子查询 关于explain 用法:explain select * from tables1 where 1 ... 先看一下在

mysql查询语句优化工具

把这个profiling功能打开,可以查看sql查询语句的整个过程中各种资源的消耗情况. mysql> show profiles;+----------+------------+---------------------------------+| Query_ID | Duration   | Query                           |+----------+------------+---------------------------------+|      

【转】Mysql查询语句优化策略

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from

公司一哥们整理的mysql查询语句优化

1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from

mysql查询语句优化

用explain优化了一个营业日汇总报表的查询.将一处type为all的查询改为range. sql是一个报表使用: EXPLAIN SELECT DATE_FORMAT(t1.business_date,'%Y-%m-%d') AS business_date, IF(t3.people_num>0, (t1.need_pay_amount/t3.people_num),0) AS avg_people_money,.. FROM ( SELECT (SUM(timer_charge) + S

mysql 查询语句优化实例

170727、MySQL查询性能优化

MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下我们从数据库的索引和查询语句的设计两个角度介绍如何提高MySQL查询性能. 数据库索引 索引是存储引擎中用于快速找到记录的一种数据结构.索引有多种分类方式,按照存储方式可以分为:聚簇索引和非聚簇索引:按照数据的唯一性可以分为:唯一索引和非唯一索引:按照列个数可以分为:单列索引和多列索引等.索引也有多

MySQL 查询语句使用进阶

MySQL 查询语句使用进阶 =============================================================================== 概述: =============================================================================== 练习: 练习1  首先导入hellodb.sql的脚本文件,查询其数据库和表如下: [[email protected] ~]# mysql 

mysql查询语句

mysql查询语句常用SELECT命令打印当前的日期和时间select now();打印当前的日期select curdate();打印当前时间select curtime();查看当前版本select version();打印当前用户select user();查看当前数据库实例select database();查看系统中可用的变量show variables;查看系统中全局变量show global variables;一般查询系统可用变量或是全局变量都是通过like的方式来进行查询的,因

【个人笔记】MySQL查询语句

最近学习了MySQL,分享一点其中查询语句的使用 语法:select  显示的内容  from  查询的范围   where   查询的条件 (显示全部内容用'*'号) 一.as 别名(可省略as) 例:select   stuname  as  '学生姓名'   form   t_student   where  stuname='张三',此句的意思是将学生表中姓名为'张三'的学生筛选出来,并将选出来的列重新命名为'学生姓名'. 二.distinct  筛选重复的数据 三.筛选条件有: and