-
SQL语句优化
- 如果是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'");
上面两条SQL语句的差别就是 CURDATE() ,MySQL的查询缓存对这个函数不起作用。所以,像 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的。所以,你所需要的就是用一个变量来代替MySQL的函数,从而开启缓存。
-
开启慢日志查询来找出慢查询,再用用explain分析SQL语句
-
避免使用select *
-
不要ORDER BY RAND()
这是效率很低的一种随机查询
-
尽量拆分大的SQL语句
-
or改成in,or的时间复杂度是o(n),in的时间复杂度是log(n),但是in的个数建议在200以内
-
尽量避免在where语句中使用!=或<>,这样会进行全表扫描。
-
对于连续的数值,使用between,而不用in
-
对于列表的数据,用limit进行分页
-
避免在where语句中进行null值判断,否则放弃使用索引而进行全表扫描
-
建表字段的优化考虑
- 如果字段的值固定且有限,建议使用enum,而不是varchar,enum类型是非常紧凑的,实际上保存的是tinyint
- 尽量使用not null,null需要额外的空间进行存储,并且在比较的时候,会比较复杂
-
IP地址存成 UNSIGNED INT
很多程序员都会创建一个 VARCHAR(15) 字段来存放字符串形式的IP而不是整形的IP。如果你用整形来存放,只需要4个字节,并且你可以有定长的字段。而且,这会为你带来查询上的优势,尤其是当你需要使用这样的WHERE条件:IP between ip1 and ip2。
我们必需要使用UNSIGNED INT,因为 IP地址会使用整个32位的无符号整形
-
固定长度的表会查询更快,即表中所有的字段都是固定长度。如表中无:varchar,text,blob等变长字段。因为固定长度的字段很容易计算下一个数据的偏移量,所有读取也会非常的快,如果不是固定长度的字段,查找下一个,需查询主键。并且,固定长度的表,会更容易被缓存和重建。但是副作用是,固定长度的字段会浪费一些空间。
-
垂直分割表。把一张表分割层几张表,降低表的复杂度和字段数目。但是分割后的表不要经常进行join。
-
越小的列会越快
-
针对性的创建索引
-
选择正确的存储引擎
一、MyISAM
MyISAM引擎是MySQL 5.1及之前版本的默认引擎,它的特点是:
1、不支持行锁,读取时对需要读到的所有表加锁,写入时则对表加排它锁 2、不支持事务
3、不支持外键
4、不支持崩溃后的安全恢复
5、在表有读取查询的同时,支持往表中插入新纪录
6、支持BLOB和TEXT的前500个字符索引,支持全文索引
7、支持延迟更新索引,极大提升写入性能
8、对于不会进行修改的表,支持压缩表,极大减少磁盘空间占用
二、InnoDB
InnoDB在MySQL 5.5后成为默认索引,它的特点是:
1、支持行锁,采用MVCC来支持高并发
2、支持事务
3、支持外键
4、支持崩溃后的安全恢复
5、不支持全文索引
总体来讲,MyISAM适合SELECT密集型的表,而InnoDB适合INSERT和UPDATE密集型的表