MySQL 性能优化

1.查询缓存优化查询
大多数的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'"); 

CURDATE(),NOW(),RAND()等此类的函数不会开启查询缓存,需要开启一个变量来代替mysql的函数,从而开启缓存。

2.只取一行数据时使用LIMIT 1
当查询表时返回结果只会是一条数据的时候,加上LIMIT 1可以增加性能,这样一来,数据库会在找到记录时停止搜索

//没有效率的
select *from user where age = 18 ;
//有效率的
select 1 from user limit 1 where age = 18;

3.为常用字段建立索引

这里写图片描述

但是建立索引不适用于在一篇大的文章中搜索一个词的情况。

4.在Join表的时候使用相当类型的例,并将其索引

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

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

5.千万不要 ORDER BY RAND()

// 千万不要这样做: 
$r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1"); 
 // 这要会更好: 
$r = mysql_query("SELECT count(*) FROM user"); 
$d = mysql_fetch_row($r); 
$rand = mt_rand(0,$d[0] - 1); 
$r = mysql_query("SELECT username FROM user LIMIT $rand, 1"); 

6.避免 SELECT *

这个很好理解,查询的东西越多,就越耗时,要取什么就查什么

select name from user

7.最好不要给数据库留NULL,尽可能使用NOT NULL

备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。
不要以为 NULL 不需要空间,比如:char(100) 型,在字段建立时,空间就固定了, 不管是否插入值(NULL也包含在内),都是占用 100个字符的空间的,如果是varchar这样的变长字段, null 不占用空间。

可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

select id from t where num = 0

8.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。

9.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,
如:

select id from t where num=10 or Name = 'admin'

可以这样查询:

select id from t where num = 10
union all
select id from t where Name = 'admin'

10.5.in 和 not in 也要慎用,否则会导致全表扫描,如:

select id from number where num in(1,2,3)

11.如果在 where 子句中使用参数,也会导致全表扫描。
因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:

//效率低
select id from t where num = @num
//可以改为强制查询使用索引
select id from t with(index(索引名)) where num = @num

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

//效率低
select id from t where num/2 = 100
//正确做法
select id from t where num = 100*2

12.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。

13.select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。

14.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值