如何优化SQL?

来源:互联网 发布:广州网络宽带资费标准 编辑:程序博客网 时间:2024/06/14 12:06

通常,网站的性能瓶颈在数据库查询,如果你希望你的网站在一定阶段之内保持稳定,优化你的SQL和数据库是非常必要的优化环节。

优化数据库是一个很大的话题,这里只是摘要一些比较关键的优化参考建议,并且需要具体分析项目的情况才能给出最合理的优化建议,所以具体的优化建议你应该咨询你公司的架构师或者DBA。

1. 选择合适的存储引擎

MySQL 为例,常用的有两个存储引擎 MyISAMInnoDB,它们各有利弊。

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

InnoDB 支持行锁,于是在写操作比较多的时候,会更优秀。并且它还支持更多的高级应用,比如:事务和外键。

2. 优化字段的数据类型

记住一个原则,越小的列会越快。对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈。所以,把你的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问。

如果一个表只有几列数据(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多。当然,你也需要保留足够的扩展空间。

3. 为搜索字段添加索引

索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你会经常用来做搜索,那么最好是为其建立普通索引,除非你要搜索的字段是大的文本字段,那应该建立全文索引。

4. 避免使用 Select *

从数据库里读出越多的数据,查询就会越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器,这还会增加网络传输的负载。即使你要查询数据表的所有字段,也尽量不要用 * 通配符,把所有的字段列出来也比 * 通配符的查询效率高。

5. 尽可能的使用 NOT NULL

除非你有很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL,并给一个默认值。 NULL 需要额外的空间,当然,并不是说你就不能使用NULL了,现实情况是很复杂的,有些情况下,你需要使用NULL值。

6. 固定长度的表会更快

如果表中的所有字段都是固定长度的,整个表会被认为是 “static” 或 “fixed-length”。

表中如果没有VARCHAR、TEXT和BLOB这些类型的字段,就是固定长度的 。只要你包括了其中一个类型的字段,这个表就不是固定长度静态表,这样,MySQL 引擎会用另一种方法来处理。

固定长度的表会提高性能,因为MySQL搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量,所以查询很快。而如果字段不是定长的,那么每次要找下一条的话,需要程序找到主键。

固定长度的表也更容易被缓存和重建。唯一的缺点是,固定长度的字段会浪费一些空间,因为定长的字段无论你用不用,都是要分配那么多的空间。可使用垂直分割技术,把表分割为两个,一个定长的,一个不是定长的。

7. 使用垂直分割技术

“垂直分割”是把一张复杂的数据表按列分割成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。

例如:在user表中有一个字段是家庭地址,这个字段是可选字段,和其他的字段相比,你并不需要经常操作这个字段。那么,就可以把它放到另外一张表中, 这样会让user表有更好的性能。对于用户表来说,只有用户ID、用户名、密码、用户角色等会被经常使用。小一点的表总是会有好的性能。

8. 使用EXPLAIN或DESC分析SELECT查询语句

使用 EXPLAIN 或 DESC 关键字分析SQL查询语句,可以知道MySQL是如何处理你的SQL语句的。

EXPLAIN 的结果会显示,SQL语句中索引的使用情况,要查询的数据是如何在表中进行搜索扫描和排序的等等。

9. 不要使用 ORDER BY RAND() 随机排序

一些新手程序员,喜欢使用 ORDER BY RAND() 命令,来对查询结果进行随机排序,然后取出几条记录。但这却严重影响了性能,如果真的需要随机显示几条数据,可通过其他更好的方法来实现。

0 0