mysql服务器常见的优化方法

1.查询时,能不用* 就不用,尽量写全字段名。

2.索引不是越多越好,每个表控制在6个索引以内。范围where条件的情况下,索引不起作用,比如where value<100

3.大部分情况连接效率远大于子查询,但是有例外。当你对连接查询的效率都感到不能接受的时候可以试试用子查询,虽然大部分情况下你会更失望,但总有碰到惊喜的时候不是么…

4.多用explain 和 profile分析查询语句

5.有时候可以1条大的SQL可以分成几个小SQL顺序执行,分了吧,速度会快很多。

6.每隔一段时间用alter table table_name engine=innodb;优化表

7.连接时注意:小表 jion 大表的原则

8.学会用explain 和 profile判断是什么原因使你的SQL慢。

9.查看慢查询日志,找出执行时间长的SQL试着优化去吧~~

优化Group By语句
默认情况下,MySQL 排序所有GROUP BY col1,col2,....。查询的方法如同在查询中指定ORDER BY col1,col2,...。如果显式包括一个包含相同的列的ORDER BY子句,MySQL 可以毫不减速地对它进行优化,尽管仍然进行排序。如果查询包括GROUP BY 但你想要避免排序结果的消耗,你可以指定ORDER BY NULL禁止排序。
 
优化Order by语句
在某些情况中,MySQL 可以使用一个索引来满足ORDER BY 子句,而不需要额外的排序。where 条件和order by 使用相同的索引,并且order by 的顺序和索引顺序相同,并且order by 的字段都是升序或者都是降序。
 
优化insert语句
如果你同时从同一客户插入很多行,使用多个值表的INSERT 语句。这比使用分开 INSERT 语句快(在一些情况中几倍)。

 代码如下 复制代码
Insert into test values(1,2),(1,3),(1,4)…

 
如果你从不同客户插入很多行,能通过使用INSERT DELAYED 语句得到更高的速度。Delayed 的含义是让insert 语句马上执行,其实数据都被放在内存的队列中,并没有真正的写入磁盘;这比每条语句都分别插入要快的多;LOW_PRIORITY刚好相反,在所有其他用户对表的读写完成后才进行插入。
 
将索引文件和数据文件分在不同的磁盘上存放(利用建表中的选项);
如果进行批量插入,可以增加bulk_insert_buffer_size 变量值的方法来提高速度,但是,这只能对myisam表使用
 
当从一个文本文件装载一个表时,使用LOAD DATA INFILE。这通常比使用很多INSERT语句快20倍;
根据应用情况使用replace 语句代替insert;
根据应用情况使用ignore 关键字忽略重复记录。
 
大批量插入数据
1. 对于Myisam 类型的表,可以通过以下方式快速的导入大量的数据。

 代码如下 复制代码
ALTER TABLE tblname DISABLE KEYS;
loading the data
ALTER TABLE tblname ENABLE KEYS;

这两个命令用来打开或者关闭Myisam 表非唯一索引的更新。在导入大量的数据到一个非空的Myisam 表时,通过设置这两个命令,可以提高导入的效率。对于导入大量数据到一个空的Myisam 表,默认就是先导入数据然后才创建索引的,所以不用进行设置。
 
2. 而对于Innodb 类型的表,这种方式并不能提高导入数据的效率。对于Innodb 类型的表,我们有以下几种方式可以提高导入的效率:
a. 因为Innodb 类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效的提高导入数据的效率。如果Innodb 表没有主键,那么系统会默认创建一个内部列作为主键,所以如果可以给表创建一个主键,将可以利用这个优势提高导入数据的效率。
 
b. 在导入数据前执行SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SETUNIQUE_CHECKS=1,恢复唯一性校验,可以提高导入的效率。
c. 如果应用使用自动提交的方式,建议在导入前执行SET AUTOCOMMIT=0,关闭自动提交,导入结束后再执行SET AUTOCOMMIT=1,打开自动提交,也可以提高导入的效率。
 
查询的优化
读为主可以设置low_priority_updates=1,写的优先级调低,告诉MYSQL尽量先处理读求
 
 
为查询缓存优化你的查询
大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中,这样,后续的相同的查询就不用操作表而直接访问缓存结果了。

这里最主要的问题是,对于程序员来说,这个事情是很容易被忽略的。因为,我们某些查询语句会让MySQL不使用缓存。请看下面的示例:

 代码如下 复制代码
// 查询缓存不开启
$r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()");
 
// 开启查询缓存
$today = date("Y-m-d");
$r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'");

 
拆分大的 DELETE 或 INSERT 语句
如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,你需要非常小心,要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。

Apache 会有很多的子进程或线程。所以,其工作起来相当有效率,而我们的服务器也不希望有太多的子进程,线程和数据库链接,这是极大的占服务器资源的事情,尤其是内存。

如果你把你的表锁上一段时间,比如30秒钟,那么对于一个有很高访问量的站点来说,这30秒所积累的访问进程/线程,数据库链接,打开的文件数,可能不仅仅会让你泊WEB服务Crash,还可能会让你的整台服务器马上?炝恕?/p>

所以,如果你有一个大的处理,你定你一定把其拆分,使用 LIMIT 条件是一个好的方法。下面是一个示例:

 代码如下 复制代码

while (1) {
    //每次只做1000条
    mysql_query("DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000");
    if (mysql_affected_rows() == 0) {
        // 没得可删了,退出!
        break;
    }
    // 每次都要休息一会儿
    usleep(50000);
}

 

where语句的优化
1.尽量避免在 where 子句中对字段进行表达式操作

 代码如下 复制代码
select id from uinfo_jifen where jifen/60 > 10000;
优化后:
Select id from uinfo_jifen where jifen>600000;

2.应尽量避免在where子句中对字段进行函数操作,这将导致mysql放弃使用索引

 代码如下 复制代码

select uid from imid where datediff(create_time,'2011-11-22')=0
优化后
select uid from imid where create_time> ='2011-11-21‘ and create_time<‘2011-11-23’;

 

索引的优化
MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。

尽量不要写!=或者<>的sql,用between或> and <代替,否则可能用不到索引

Order by 、Group by 、Distinct 最好在需要这个列上建立索引,利于索引排序

尽量利用mysql索引排序

没办法的情况下,使用强制索引Force index(index_name)

尽量避勉innodb用非常大尺寸的字段作为主键

较频繁的作为查询条件的字段应该创建索引;

选择性高的字段比较适合创建索引;

作为表关联字段一般都需要创索引.

更新非常频繁的字段不适合创建索引;

不会出现在 WHERE 子句中的字段不该创建索引.

选择性太低的字段不适合单独创建索引

 

尽量不要用子查询


 代码如下
复制代码


mysql> explain select uid_,count(*) from smember_6 where uid_ in (select uid_ from alluid) group by uid_;
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-----------+-------+---------------+---------+---------+------+----------+--------------------------+
| 1 | PRIMARY | smember_6 | index | NULL | PRIMARY | 8 | NULL | 53431264 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | alluid | ALL | NULL | NULL | NULL | NULL | 2448 | Using where |



--优化后



| mysql> explain select a.uid_,count(*) from smember_6 a,alluid b where a.uid_=b.uid_ group by uid_;
+----+-------------+-------+------+---------------+---------+---------+------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+---------+---------+------------+------+---------------------------------+
| 1 | SIMPLE | b | ALL | NULL | NULL | NULL | NULL | 2671 | Using temporary; Using filesort |
| 1 | SIMPLE | a | ref | PRIMARY | PRIMARY | 4 | ssc.b.uid_ | 1 | Using index



 

 

Join的优化
如果你的应用程序有很多 JOIN 查询,你应该确认两个表中Join的字段是被建过索引的。这样,MySQL内部会启动为你优化Join的SQL语句的机制。
而且,这些被用来Join的字段,应该是相同的类型的。例如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行。(两个表的字符集有可能不一样)
 

表的优化

尽可能的使用 NOT NULL
除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。
不要以为 NULL 不需要空间,其需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。
当然,这里并不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。
下面摘自MySQL自己的文档:
“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”

explain 分析

select ….
变体:
1.explain extended select ….
将执行计划“反编译”成select语句;
运行show warnings 可以得到被mysql优化器优化后的语句
2.explain partitions select …
用于分区表的explain
运行结果含义:
type: all ,index,range,ref,eq_ref,const,system null  从左到右,最差到最好;
all: full table scan ;mysql将遍历全表以找到匹配的行;
index : index scan; index 和 all的区别在于index类型只遍历索引;
range:索引范围扫描,对索引的扫描开始于某一点,返回匹配值的行,常见与between ,< ,>等查询;
ref:非唯一性索引扫描,返回匹配某个单独值的所有行,常见于使用非唯一索引即唯一索引的非唯一前缀进行查找;
eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常用于主键或者唯一索引扫描;
const,system:当mysql对某查询某部分进行优化,并转为一个常量时,使用这些访问类型。如果将主键置于where列表中,mysql就能将该查询转化为一个常量。
possible keys:
指出mysql能使用哪个索引在表中找到行,查询涉及到的字段若存在索引,则该索引被列出,但是不一定被查询使用。
key:显示mysql在查询中实际使用的索引,若没有使用索引,则显示为null。
key_len:表示索引中使用的字节数,可以通过该列计算查询中使用的索引的长度。key_len显示的值为索引字段的最大长度,并非实际使用长度。即key_len是根据表定义计算而得,不是通过表内检索出的。
ref:表示上述表的连接匹配条件,即哪些列或者常量被用于查找索引上的值;
rows:表示mysql根据表统计信息以及索引选用情况,估算的找到所需记录所需要的行数;
extra:包含不适合在其他列中显示但是十分重要的额外信息
a:using index:该值表示相迎的select操作中使用了覆盖索引(cover index)
b:using where:表示mysql服务器再存储引擎受到记录后进行“后过滤”;
c:using temporary :表示mysql需要使用临时表来存储结果集,常见于排序和分组查询;
d:using filesort:mysql中无法利用索引完成排序,称为“文件排序”;
explain局限:
explain不会告诉你关于触发器,存储过程的信息或者用户自定义的函数对查询的影响情况。
explain不会考虑cache。

 

时间: 2024-09-24 04:07:12

mysql服务器常见的优化方法的相关文章

MySQL order by性能优化方法实例

  这篇文章主要介绍了MySQL order by性能优化方法实例,本文讲解了MySQL中order by的原理和优化order by的三种方法,需要的朋友可以参考下 前言 工作过程中,各种业务需求在访问数据库的时候要求有order by排序.有时候不必要的或者不合理的排序操作很可能导致数据库系统崩溃.如何处理好order by排序呢?本文从原理以及优化层面介绍 order by . 一 MySQL中order by的原理 1 利用索引的有序性获取有序数据 当查询语句的 order BY 条件和

MySQL延迟关联性能优化方法

  这篇文章主要介绍了MySQL延迟关联性能优化方法,本文讲解了延迟关联的背景.延迟关联的分析.延迟关联的解决等内容,需要的朋友可以参考下 [背景] 某业务数据库load 报警异常,cpu usr 达到30-40 ,居高不下.使用工具查看数据库正在执行的sql ,排在前面的大部分是: 代码如下: SELECT id, cu_id, name, info, biz_type, gmt_create, gmt_modified,start_time, end_time, market_type, b

mysql服务器集群配置方法

mysql服务器集群配置方法 mysql-cluster安装 系统 centos5.1 32位(如何是64位下相应64位的rpm包) http://dev.mysql.com/get/downloads/mysql-cluster-7.0和下面的包名对应 一共有5个包: mysql-cluster-gpl-client-7.1.3-1.rhel5.i386.rpm mysql-cluster-gpl-management-7.1.3-1.rhel5.i386.rpm mysql-cluster-

linux服务器常见错误代码问题解决方法

&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;   Red Hat是全球最大的开源技术厂家,其产品Red Hat Linux也是全世界应用最广泛的Linux.Red Hat公司总部位于美国北卡罗来纳州.在全球拥有22个分部.  对于Red Hat来说,开放源代码已经不只是一个软件模型,这正是Red Hat的商业模式.因为Red Hat坚信只有协作,企业才能创造出非凡质量和价值的产品. 在Red Hat的300名工

Android中ListView的几种常见的优化方法总结

Android中的ListView应该算是布局中几种最常用的组件之一了,使用也十分方便,下面将介绍ListView几种比较常见的优化方法: 首先我们给出一个没有任何优化的Listview的Adapter类,我们这里都继承自BaseAdapter,这里我们使用一个包含100个字符串的List集合来作为ListView的项目所要显示的内容,每一个条目都是一个自定义的组件,这个组件中只包含一个textview: Activity: package com.alexchen.listviewoptimi

MySQL Order By索引优化方法_Mysql

尽管 ORDER BY 不是和索引的顺序准确匹配,索引还是可以被用到,只要不用的索引部分和所有的额外的 ORDER BY 字段在 WHERE 子句中都被包括了. 使用索引的MySQL Order By 下列的几个查询都会使用索引来解决 ORDER BY 或 GROUP BY 部分: 复制代码 代码如下: SELECT * FROM t1 ORDER BY key_part1,key_part2,... ; SELECT * FROM t1 WHERE key_part1=constant ORD

在ubuntu中重置mysql服务器root密码的方法_Mysql

首先停止mysql服务: 复制代码 代码如下: root@webserver:/home/webmaster# service mysql stop 接着采用忽略密码认证模式重新创建一个mysql服务: 复制代码 代码如下: root@webserver:/home/webmaster# mysqld --user=mysql --skip-grant-tables --skip-networking & 成功启动后返回PID及其它启动信息 复制代码 代码如下: [1] 3591 root@we

千万级的mysql数据库与sql优化方法

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

Mysql数据表的优化方法总结

优化表的数据类型 表需要使用何种数据类型,是需要根据应用来判断的.虽然应用设计的时候需要考虑字段的长度留有一定的冗余,但是不推荐让很多字段都留有大量的冗余,这样即浪费存储也浪费内存. 我们可以使用PROCEDURE ANALYSE()对当前已有应用的表类型的判断,该函数可以对数据表中的列的数据类型提出优化建议,可以根据应用的实际情况酌情考虑是否实施优化.语法:  代码如下 复制代码    SELECT * FROM tbl_name PROCEDURE ANALYSE();    SELECT