mysql的性能优化总结

经验是从别人那里拿来的,不想直接复制黏贴,想亲自总结下,巴拉巴拉.........进入正题吧php

1、为查询加入缓存html

一、检查数据库是否开启缓存:show variables like '%query_cache%'; 若开启query_cache_type 为 ONmysql

二、设置查询缓存的方法:网上搜素下:http://www.111cn.net/database/mysql/63815.htm(参考连接)web

使用缓存和不适用缓存的区别sql


$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'");;
二者惟一区别就是CURDATE(),查询缓存对这个函数不起做用,项now()和rand()或者其余sql函数均不会开启查询缓存,因此必须新增一个变量来代替mysql的函数,从而开启缓存

2、EXPLAIN 你的 SELECT 查询shell

查看rows列可让咱们找到潜在的性能问题。数据库

3、当只要一条数据时,使用limit1,性能会大大提高缓存

这样mysql会在找到一条数据后中止搜索,而不是继续日后查下一条符合记录的数据服务器

下面的示例,只是为了找一下是否有“中国”的用户,很明显,后面的会比前面的更有效率。(请注意,第一条中是Select *,第二条是Select 1)网络

$r = mysql_query("SELECT * FROM user WHERE country = 'China'");
if (mysql_num_rows($r) > 0) {
    // ...
}
 
// 有效率的:
$r = mysql_query("SELECT 1 FROM user WHERE country = 'China' LIMIT 1");
if (mysql_num_rows($r) > 0) {
    // ...
}

4、为搜索字段加上索引

索引并不必定只是给主键和惟一的字段,加上索引,而是若是有某个字段常常会用到,则为其加上索引

若是某个字段查询时如 like“a%”,则能够用上索引,可是若是想like“%a%”则索引没意义

5、在使用join时,两个表的字段类型要一致,,并且是被索引过的,myql内部会启为你优化join的字段

被join的字段应该是相同类型的。例如:若是你要把 DECIMAL 字段和一个 INT 字段Join在一块儿,MySQL就没法使用它们的索引。对于那些STRING类型,还须要有相同的字符集才行。(两个表的字符集有可能不同)

$r = mysql_query("SELECT company_name FROM users
    LEFT JOIN companies ON (users.state = companies.state)
    WHERE users.id = $user_id");
 
// 两个 state 字段应该是被建过索引的,并且应该是至关的类型,相同的字符集。

6、不要用select * 应该使用什么字段就去取什么字段,由于从数据库读越多的数据查询就越慢,并且若是时web服务器和数据库服务器时两台独立的服务器还会增长网络传输的负载

7、永远为每张表设置一个主键id

类型最好时int型的,varchar会使得性能降低, 推荐使用UNSIGNED),并设置上自动增长的AUTO_INCREMENT标志。 在这里,只有一个状况是例外,那就是“关联表”的“外键”,也就是说,这个表的主键,经过若干个别的表的主键构成。咱们把这个状况叫作“外键”。好比:有一个“学生表”有学生的ID,有一个“课程表”有课程ID,那么,“成绩表”就是“关联表”了,其关联了学生表和课程表,在成绩表中,学生ID和课程ID叫“外键”其共同组成主键。

8、使用enum而不是varchar,

ENUM 类型是很是快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来作一些选项列表变得至关的完美。

若是你有一个字段,好比“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限并且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。

MySQL也有一个“建议”(见第十条)告诉你怎么去从新组织你的表结构。当你有一个 VARCHAR 字段时,这个建议会告诉你把其改为 ENUM 类型。使用 PROCEDURE ANALYSE() 你能够获得相关的建议。

 

9、尽量使用not null

空值('')是不占用空间的
NULL值是未知的,且占用空间,不走索引,DBA建议建表的时候最好设置字段是NOT NULL 来避免这种低效率的事情的发生。
注意:
count()统计某列的记录数的时候,若是采用的NULL值,会别系统自动忽略掉,可是空值是会进行统计到其中的。
对于timestamp数据类型,若是往这个数据类型插入的列插入NULL值,则出现的值是当前系统时间。插入空值,则会出现 '0000-00-00 00:00:00'

 10、IP地址 地址存成 UNSIGNED INT

11、固定长度的表会更快

若是表中全部的字段都时固定长度,则整个表会被认为是static或者fixed-length 例如,表中没有以下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了

12、垂直分割

就是一个大表切割成多个小表,能够下降表的复杂度和字段的数目,从而达到优化

实例1:在user表中有一个字段是家庭地址等啊,在这个表中除了我的信息除外,并不常读取和改写这个字段,何不吧他放倒另一张表中,这样会提升 表的性能

实例2:这个表中有一个是last——login的字段,每次登陆完毕都会更新,可是每次更新时都会吧表的查询缓存清空,因此能够吧这个字段放倒另一个表中,这样就不会影响你对username等字段的频繁查询,由于查询缓存会提升性能。查询缓存保留了返回客户端数据的完整结果,当缓存被命中时,服务器会立刻返回保存的结果,而且跳过解析,优化和执行的步骤,缓存也须要开销,只有在节省的资源大于开销的时候,缓存才会真正的油效率,这和服务器的负载有关

十3、拆分大的delete和insert语句

由于会锁表,会形成web crash

十4、越小的列越快

若是一个表只会有几列罢了(好比说字典表,配置表),那么,咱们就没有理由使用 INT 来作主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。若是你不须要记录时间,使用 DATE 要比 DATETIME 好得多。

十5、选择正确的搜索引擎:

在 MySQL 中有两个存储引擎 MyISAM 和 InnoDB,每一个引擎都有利有弊。酷壳之前文章《MySQL: InnoDB 仍是 MyISAM?》讨论和这个事情。

MyISAM 适合于一些须要大量查询的应用,但其对于有大量写操做并非很好。甚至你只是须要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都没法操做直到读操做完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。

InnoDB 的趋势会是一个很是复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,因而在写操做比较多的时候,会更优秀。而且,他还支持更多的高级应用,好比:事务。

16. 当心“永久连接”

“永久连接”的目的是用来减小从新建立MySQL连接的次数。当一个连接被建立了,它会永远处在链接的状态,就算是数据库操做已经结束了。并且,自从咱们的Apache开始重用它的子进程后——也就是说,下一次的HTTP请求会重用Apache的子进程,并重用相同的 MySQL 连接。

在理论上来讲,这听起来很是的不错。可是从我的经验(也是大多数人的)上来讲,这个功能制造出来的麻烦事更多。由于,你只有有限的连接数,内存问题,文件句柄数,等等。

并且,Apache 运行在极端并行的环境中,会建立不少不少的了进程。这就是为何这种“永久连接”的机制工做地很差的缘由。在你决定要使用“永久连接”以前,你须要好好地考虑一下你的整个系统的架构。

相关文章
相关标签/搜索