Mysql优化技巧

索引优化,查询优化,查询缓存,服务器设置优化,操作系统和硬件优化,应用层面优化(web服务器,缓存)等等。这里的记录的优化技巧更适用于开发人员,都是从网络上收集和自己整理的,主要是查询语句上面的优化,其它层面的优化技巧在此不做记录。

建立索引的几个准则:

(1)、合理的建立索引能够加速数据读取效率,不合理的建立索引反而会拖慢数据库的响应速度。

(2)、索引越多,更新数据的速度越慢。

(3)、尽量在采用MyIsam作为引擎的时候使用索引(因为MySQL以BTree存储索引),而不是InnoDB。但MyISAM不支持Transcation。

(4)、当你的程序和数据库结构/SQL语句已经优化到无法优化的程度,而程序瓶颈并不能顺利解决,那就是应该考虑使用诸如memcached这样的分布式缓存系统的时候了。

(5)、习惯和强迫自己用EXPLAIN来分析你SQL语句的性能。


1count的优化

比如:计算id大于5的城市


(1). select count(*) from world.city where id > 5;

(2). select (select count() from world.city) – count() from world.city where id <= 5;


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


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

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


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


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

尽量避免在WHERE子句中对字段进行函数或表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

SELECT * FROM T1 WHERE F1/2=100 应改为: SELECT * FROM T1 WHERE F1=100*2


4避免使用!=或<>、IS NULL或IS NOT NULL、IN ,NOT IN等这样的操作符

因为这会使系统无法使用索引,而只能直接搜索表中的数据。例如: SELECT id FROM employee WHERE id != “B%” 优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。在in语句中能用exists语句代替的就用exists.


5尽量使用数字型字段

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


6合理使用EXISTS,NOT EXISTS子句

如下所示:

(1). SELECT SUM(T1.C1) FROM T1 WHERE (SELECT COUNT(*)FROM T2 WHERE T2.C2=T1.C2>0)

(2). SELECT SUM(T1.C1) FROM T1WHERE EXISTS(SELECT * FROM T2 WHERE T2.C2=T1.C2)


两者产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁定的表扫描或是索引扫描。如果你想校验表里是否存在某条纪录,不要用count(*)那样效率很低,而且浪费服务器资源。可以用EXISTS代替。如:

IF (SELECT COUNT() FROM table_name WHERE column_name = ‘xxx’)可以写成:IF EXISTS (SELECT FROM table_name WHERE column_name = ‘xxx’)


7能够用BETWEEN的就不要用IN


8能够用DISTINCT的就不用GROUP BY


9尽量不要用SELECT INTO语句。SELECT INTO 语句会导致表锁定,阻止其他用户访问该表


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

SELECT * FROM T1 WHERE nextprocess = 1 AND processid IN (8,32,45) 改成:

SELECT * FROM T1 (INDEX = IX_ProcessID) WHERE nextprocess = 1 AND processid IN (8,32,45)

则查询优化器将会强行利用索引IX_ProcessID 执行查询。


11消除对大型表行数据的顺序存取

尽管在所有的检查列上都有索引,但某些形式的WHERE子句强迫优化器使用顺序存取。如:

SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008

解决办法可以使用并集来避免顺序存取:

SELECT * FROM orders WHERE customer_num=104 AND order_num>1001 UNION SELECT * FROM orders WHERE order_num=1008

这样就能利用索引路径处理查询。【jacking 数据结果集很多,但查询条件限定后结果集不大的情况下,后面的语句快】


12尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引

见如下例子:

SELECT * FROM T1 WHERE NAME LIKE ‘%L%’

SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’

SELECT * FROM T1 WHERE NAME LIKE ‘L%’

即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作,不要习惯性的使用 ‘%L%’这种方式(会导致全表扫描),如果可以使用`L%’相对来说更好;


13虽然UPDATE、DELETE语句的写法基本固定,但是还是对UPDATE语句给点建议

(1). 尽量不要修改主键字段。

(2). 当修改VARCHAR型字段时,尽量使用相同长度内容的值代替。

(3). 尽量最小化对于含有UPDATE触发器的表的UPDATE操作。

(4). 避免UPDATE将要复制到其他数据库的列。

(5). 避免UPDATE建有很多索引的列。

(6). 避免UPDATE在WHERE子句条件中的列。


14能用UNION ALL就不要用UNION

UNION ALL不执行SELECT DISTINCT函数,这样就会减少很多不必要的资源

在跨多个不同的数据库时使用UNION是一个有趣的优化方法,UNION从两个互不关联的表中返回数据,这就意味着不会出现重复的行,同时也必须对数据进行排序,我们知道排序是非常耗费资源的,特别是对大表的排序。

UNION ALL可以大大加快速度,如果你已经知道你的数据不会包括重复行,或者你不在乎是否会出现重复的行,在这两种情况下使用UNION ALL更适合。此外,还可以在应用程序逻辑中采用某些方法避免出现重复的行,这样UNION ALL和UNION返回的结果都是一样的,但UNION ALL不会进行排序。


15字段数据类型优化

(1). 避免使用NULL类型:NULL对于大多数数据库都需要特殊处理,MySQL也不例外,它需要更多的代码,更多的检查和特殊的索引逻辑,有些开发人员完全没有意识到,创建表时NULL是默认值,但大多数时候应该使用NOT NULL,或者使用一个特殊的值,如0,-1作为默认值。

(2). 尽可能使用更小的字段,MySQL从磁盘读取数据后是存储到内存中的,然后使用cpu周期和磁盘I/O读取它,这意味着越小的数据类型占用的空间越小,从磁盘读或打包到内存的效率都更好,但也不要太过执着减小数据类型,要是以后应用程序发生什么变化就没有空间了。修改表将需要重构,间接地可能引起代码的改变,这是很头疼的问题,因此需要找到一个平衡点。

(3). 优先使用定长型


16关于大数据量limit分布的优化(当偏移量特别大时,limit效率会非常低)

附上一个提高limit效率的简单技巧,在覆盖索引(覆盖索引用通俗的话讲就是在select的时候只用去读取索引而取得数据,无需进行二次select相关表)上进行偏移,而不是对全行数据进行偏移。可以将从覆盖索引上提取出来的数据和全行数据进行联接,然后取得需要的列,会更有效率,看看下面的查询:


mysql> select film_id, description from sakila.film order by title limit 50, 5;


如果表非常大,这个查询最好写成下面的样子:


mysql> select film.film_id, film.description from sakila.film


inner join(select film_id from sakila.film order by title liimit 50,5) as film usinig(film_id);


17程序中如果一次性对同一个表插入多条数据

比如以下语句:


insert into person(name,age) values(‘xboy’, 14);


insert into person(name,age) values(‘xgirl’, 15);


insert into person(name,age) values(‘nia’, 19);


把它拼成一条语句执行效率会更高.


insert into person(name,age) values(‘xboy’, 14), (‘xgirl’, 15),(‘nia’, 19);


18不要在选择的栏位上放置索引,这是无意义的。应该在条件选择的语句上合理的放置索引,比如where,order by

SELECT id,title,content,cat_id FROM article WHERE cat_id = 1;


上面这个语句,你在id/title/content上放置索引是毫无意义的,对这个语句没有任何优化作用。但是如果你在外键cat_id上放置一个索引,那作用就相当大了。


19ORDER BY语句的MySQL优化

(1). ORDER BY + LIMIT组合的索引优化。如果一个SQL语句形如:


SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort] LIMIT [offset],[LIMIT];


这个SQL语句优化比较简单,在[sort]这个栏位上建立索引即可。


(2). WHERE + ORDER BY + LIMIT组合的索引优化,形如:


SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [VALUE] ORDER BY [sort] LIMIT [offset],[LIMIT];


这个语句,如果你仍然采用第一个例子中建立索引的方法,虽然可以用到索引,但是效率不高。更高效的方法是建立一个联合索引(columnX,sort)


(3). WHERE + IN + ORDER BY + LIMIT组合的索引优化,形如:


SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] IN ([value1],[value2],…) ORDER BY [sort] LIMIT [offset],[LIMIT];


这个语句如果你采用第二个例子中建立索引的方法,会得不到预期的效果(仅在[sort]上是using index,WHERE那里是using where;using filesort),理由是这里对应columnX的值对应多个。


目前哥还木有找到比较优秀的办法,等待高手指教。


(4).WHERE+ORDER BY多个栏位+LIMIT,比如:


SELECT * FROM [table] WHERE uid=1 ORDER x,y LIMIT 0,10;


对于这个语句,大家可能是加一个这样的索引:(x,y,uid)。但实际上更好的效果是(uid,x,y)。这是由MySQL处理排序的机制造成的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/386062.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【工作经验分享】不会真有人觉得mybatis很难学吧

什么是自旋锁和互斥锁&#xff1f; 由于CLH锁是一种自旋锁&#xff0c;那么我们先来看看自旋锁是什么&#xff1f; 自旋锁说白了也是一种互斥锁&#xff0c;只不过没有抢到锁的线程会一直自旋等待锁的释放&#xff0c;处于busy-waiting的状态&#xff0c;此时等待锁的线程不会…

华为面试题

技术面试&#xff1a; java&#xff1a; java学了几年&#xff0c;看过什么书&#xff0c;有没有看过thinking in java这本书 java的公共父类是什么&#xff0c;object类中有什么方法 object中有个hashcode方法&#xff0c;这个方法是用来做什么的&#xff0c; equal 与 的区…

【工作经验分享】这些新技术你们都知道吗

前言 近年来&#xff0c;微服务架构(Microservices Architecture)已经成为一种主流的软件开发方法论&#xff0c;所谓微服务( Microservices ),就是一些具有足够小的粒度、能够相互协作且自治的服务体系。 微服务架构基于分布式系统&#xff0c;同时借助了面向服务架构和企业服…

京东面试题(JAVA)

京东17号一面问题与回答情况&#xff08;Java岗&#xff09; 作者&#xff1a;牛客190525号 Q1: HashMap的原理, 以及HashMap如何扩充bucket的大小 A1: 原理答上来了&#xff0c;如何扩容瞎答的&#xff0c;之前不知道扩容之后已经哈希的MapEntry如何处理&#xff0c;当时就…

【微信小程序】使用Hystrix的插件机制

前言 在本篇文章开始前&#xff0c;我想想来回答一个问题&#xff1a;我为什么要写这一篇关于面试的文章&#xff1f; 原因有三&#xff1a;第一&#xff0c;我想为每一个为梦想时刻准备着的”有心人“尽一份自己的力量&#xff0c;提供一份高度精华的Java面试清单&#xff1…

大话数据结构——数据结构绪论

数据&#xff1a;描述客观事物的符号&#xff0c;是计算机可以操作的对象&#xff0c;是能被计算机识别&#xff0c;并输入给计算机处理的符号集合。 有两个要素&#xff1a; 可以输入到计算机中能被计算机程序处理 数据元素&#xff1a;组成数据的基本单位&#xff0c;也就…

【微信小程序】目前最全的《Java面试题及解析》

开头 在找工作的过程中&#xff0c;对于 Redis 技术知识的掌握已经成为必须的技能。美团面试常常就会被问到Redis相关知识&#xff0c;而这次我就差点倒在了美团3面&#xff0c;面试官连问我以下几个Redis的问题&#xff0c;然后就卡壳了… redis了解吗&#xff1f;你说说怎么…

大话数据结构——算法

算法&#xff1a;算法是解决特定问题求解步骤的描述&#xff0c;在计算机中表现为指令的有限序列&#xff0c;并且每条指令表示一个或多个操作。 为什么把数据结构和算法一起说&#xff1f; 想想罗密欧与朱丽叶&#xff0c;梁山伯和祝英台&#xff0c;少了一个你总会觉得奇怪…

java线上培训班学费一般多少,成长路线图

前言 众所皆知的&#xff0c;Linux的核心原型是1991年由托瓦兹(Linus Torvalds)写出来的&#xff0c;但是托瓦兹为何可以写出Linux这个操作系统?为什么它要选择386的计算机来开发?为什么Linux的发展可以这么迅速?又为什么Linux是免费的?以及目前为何有这么多的 Linux版本(…

将visio的图片插入latex(png格式转换成eps格式图片)

EPS和PDF转换工具&#xff1a;http://www.xdowns.com/tag.asp?keywordEPS%D7%AApdf 这个软件亲测可以转换&#xff0c;但是&#xff0c;仍然不能插入latex中&#xff0c;就像之前曾尝试强制改变后缀名转成eps一样&#xff0c;效果是不佳的。 楼主的图是在visio上画的&#x…

java线程池使用实战,太牛了!

前言 今天这篇文章中简单介绍一下一个 Java 程序员必知的 Linux 的一些概念以及常见命令。 如果文章有任何需要改善和完善的地方&#xff0c;欢迎在评论区指出&#xff0c;共同进步&#xff01;笔芯&#xff01; 正式开始 Linux 之前&#xff0c;简单花一点点篇幅科普一下操作…

大数据基础技术和应用

大数据概述 数据的表现形式&#xff1a; 线下数据信息化&#xff1a;数据库、文字记录、照片……互联网-移动互联网&#xff1a;网页数据、用户行为记录、数字图像……传感器&#xff1a;设备监控、智能家居、摄像头…… 大数据的4V特征&#xff1a; 大量化&#xff08;Vol…

java线程池参数面试题,附赠复习资料

前言 作为同时具备高性能、高可靠和高可扩展性的典型键值数据库&#xff0c;Redis不仅功能强大&#xff0c;而且稳定&#xff0c;理所当然地成为了大型互联网公司的首选。 众多大厂在招聘的时候&#xff0c;不仅会要求面试者能简单地使用Redis&#xff0c;还要能深入地理解底…

Hadoop 大数据平台架构与实践

初识Hadoop Hadoop是一个开源的分布式存储分布式计算平台。 Hadoop核心组成部分&#xff1a; HDFS&#xff1a;分布式文件系统&#xff0c;存储海量的数据。MapReduce&#xff1a;并行处理框架&#xff0c;实现任务分解和调度。 Hadoop可以用来做什么&#xff1f; 搭建大型…

java线程池有几种,讲的太透彻了

前言 该文档在Github上收获40Kstar的Java面试神技&#xff08;这赞数&#xff0c;质量多高就不用我多说了吧&#xff09;非常全面&#xff0c;包涵Java基础、Java集合、JavaWeb、Java异常、OOP、IO与NIO、反射、注解、多线程、JVM、MySQL、MongoDB、Spring全家桶、计算机网络、…

HIVE入门

Hive概述 什么是 Hive&#xff1f; * Hive 是建立在 Hadoop HDFS 上的数据库仓库基础建构 * Hive 可以用来进行数据库提取转化加载&#xff08;ETL&#xff09; * Hive 定义了简单的类似 SQL 查询语言&#xff0c;称为 HQL&#xff0c;它允许熟悉 SQL 的用户查询数据 * Hi…

java线程面试题博客园,超详细

简介 HikariCP 是用于创建和管理连接&#xff0c;利用“池”的方式复用连接减少资源开销&#xff0c;和其他数据源一样&#xff0c;也具有连接数控制、连接可靠性测试、连接泄露控制、缓存语句等功能&#xff0c;另外&#xff0c;和 druid 一样&#xff0c;HikariCP 也支持监控…

java编写斐波那契数列,实战案例

前言 提到插件&#xff0c;相信大家都知道&#xff0c;插件的存在主要是用来改变或者增强原有的功能&#xff0c;MyBatis中也一样。然而如果我们对MyBatis的工作原理不是很清楚的话&#xff0c;最好不要轻易使用插件&#xff0c;否则的话如果因为使用插件导致了底层工作逻辑被…

用户画像

用户画像&#xff1a;标签化、 用标签描述用户行为 用户画像&#xff1a;动态信息数据 用户行为产生的数据&#xff1a;注册、浏览、点击、购买、签收、评价 比较重要的行为&#xff1a;购买商品、浏览商品、放入购物车、关注商品 用户画像的用途&#xff1a;分类统计&…

java编程代写有哪些平台,学习路线+知识点梳理

前言 今天刚好有空&#xff0c;跟大家聊聊如何学好算法进大厂。 前两天一个读者和我说&#xff0c;他坚持刷算法题2个月&#xff0c;薪资翻番去了他梦寐以求的大厂&#xff0c;期间面字节跳动还遇到了原题…其实据我所知目前国内的大厂和一些独角兽&#xff0c;已经越来越效仿…