1.使用查询缓存
大多数的MySQL服务器都开始了查询缓存,这是由MySQL查询引擎处理的;这样当出现重复的查询的时候,查询结果会放到一个缓存中,这样当再次访问的时候,会直接读取缓存;但有些情况下,某些查询语句不会使用缓存,如:
//查询缓存不开启
$res = mysql_query("SELECT username FROM users WHERE time>= CURETIME()");
//查询缓存开始
$today = date('Y-m-d');
$res = mysql_query("SELECT username FROM users WHERE time>= '$today' ");
注:mysql对NOW()和RAND()不会开启缓存,因为他们返回的结果是易变的,我们需要用一个变量来代替函数,从而开启缓存。
2.EXPLAIN你的查询
使用EXPALN关键字可以让你知道mysql如何处理你的SQL语句,这可以帮你分析你的表结构后者性能瓶颈;
EXPALN的查询结果还会告诉你你的索引主键如何被利用,你的数据博阿如何被搜索和排序等。
3.当数据只有一条的时候使用LIMIT1
如果知道查询表的结果只有一条,可以考虑使用“LIMIT 1”,由于查询的时候需要去fetch游标,这样当数据库引擎查询到一条数据以后,可以停止搜索;如:
//没有效率的
$res = mysql_query("SELECT * FROM users WHERE country = 'china' LIMIT 1 ");
//有效率的
$res = mysql_query("SELECT 1 FROM uers country = 'china' L ");
4.为索引字段建立索引
索引并不不一定就是给主键或者唯一字段的。如果你的表中的某个字段经常需要被用来搜索,那么最好为他简历索引。
有些搜索是不能使用正常的索引的,如:“WHERE post_content LIKE '%apple%' ”,索引是没有意义的,你需要使用MySQL的全文索引或者自己新建一个索引(比如说:搜索关键词或者Tag什么的)
5.在join表的时候使用相同类型的字段,并将它们索引
如果你的应用有很多JOIN查询,你应该确定这两个表中Join字段的类型是相同的,并且都被简历了索引,这样mysql内部机制才会为你启动join的sql语句。
这样被用来Join的字段,应该是相同类型的。如:将一个DECIMAL字段类型和INT类型join到一起,将无法使用到索引;另外,string类型字段的需相同的字符集。
6.千万不要使用ORDER BY RAND()
想打乱返回的数据行?直接使用RAND()会导致可怕的性能问题?示例如:
//千万不要这样做
$res = mysql_query("SELECT username FORM users ORDER BY RAND() LIMIT 1");
//这样做更好
$counts_query = mysql_query("SELECT COUNT(*) FROM users");
$counts_arr = mysql_fetch($counts_query);
$rand = mt_rand(0,$counts_arr[0]-1);
$res = mysql_query("SELECT username FROM users LIMIT $rand,1"); //有“,”
7.避免SELECT *
从数据中读取的字段越多,速度越慢;并且如果有多台数据库服务器的话,还会增加网络传输负担。
8.永远为每张表设置一个ID
我们应该为数据库中的每一张表设置一个ID作为主键,最好是一个INT类型(推荐使用UNSIGNED),并设置自动添加的AUTO_INCREMENT标志。
尽量使用INT类型作为主键,并使用表的主键构造对应的数据结构;主键的性能和设置非常重要,尤其是在集群和分区等情况下。
例外情况:“关联表”的“外键”,也就是说,这个表的主键,由若干标的表的主键构成,我们吧这个情况叫做外键;例如:有一个“学生表”有学生的ID,有一个“课程表”有课程ID,那么,“成绩表”就是“关联表”了,其关联了学生表和课程表,在成绩表中,学生ID和课程ID叫“外键”共同构成主键。
9.使用ENUM而不是VARCHAR
ENUM类型,其表存的是字符串,添加选项的时候是美剧,显示出来的是字符串;如果插入的记录不在枚举范围中,对于的字段将变为空,并对于的字段索引值为0。
建议在字段的取值有限而且固定的情况下使用。
10.使用PROCEDURE ANALYSE()取得建议
PROCEDURE ANALYSE()会帮你分析你的字段和实际的数据,并给出一个有用的建议;一些大的决定是需要数据作为基础的,并且会数据量的变化而变化。