优化您的数据库
数据库优化很快会成为一个前沿话题,我几乎没有空间在这里完全公正地做这个话题。但是如果您在寻求优化您的数据库的速度,首先应当采取一些步骤,这应当对常见问题有所帮助。
将数据库放在自己的机器上
数据库查询自身可以变得相当激烈,通常在对大小合理的数据集执行简单的 SELECT
语句时限定在 100% 的 CPU。如果您的 web 服务器和数据库服务器都在竟用单一机器上的 CPU 时间,这无疑将减慢您的请求速度。因此我想第一步最好是将 web 服务器和数据库服务器放在单独的机器上,确保您的数据库服务器是两者中更强健的(数据库服务器喜欢大量内存和多个 CPU)。
合理设计和编制表索引
数据库性能的最大问题可能源自于不良数据库设计和缺失索引。SELECT
语句通常是运行在典型 web 应用程序中的最常见的查询类型。它们也是在数据库服务器上运行的最耗时的查询。此外,这些类型的 SQL 语句对适当的索引和数据库设计最敏感,因此查看以下指示,获取实现最优性能的技巧。
NULL
值字段浪费磁盘空间。文本或 blob 等可变大小字段也是如此,其中表大小的增长可以远超过需求。在这种情况下,您应当考虑将其他栏分成不同的表,在记录的主键上将其联合起来。 分析在服务器上运行的查询
改进数据库性能的最佳方法是分析在您的数据库服务器上运行什么查询,且运行它们需要多长时间。几乎每个数据库都有具有这种功能的工具。对于 MySQL,您可以利用慢查询日志来查找有问题的查询。要使用它,在 MySQL 配置文件中将 slow_query_log
设置为 1,然后将 log_output 设置为 FILE,将它们记录到文件 hostname-slow.log 中。您可以设置 long_query_time
阈值,确定查询必须运行多少秒才被看作是 “慢查询”。我想建议将该阈值首先设置为 5 秒,随着时间的推移将其缩减为 1 秒,具体取决于您的数据集。如果您探究该文件,您会看到类似于清单 1 的详细查询。
清单 1. MySQL 慢查询日志
/usr/local/mysql/bin/mysqld, Version: 5.1.49-log, started with:Tcp port: 3306 Unix socket: /tmp/mysql.sockTime Id Command Argument# Time: 030207 15:03:33# User@Host: user[user] @ localhost.localdomain [127.0.0.1]# Query_time: 13 Lock_time: 0 Rows_sent: 117 Rows_examined: 234use sugarcrm;select * from accounts inner join leads on accounts.id = leads.account_id; |
我们想要考虑的关键对象是 Query_time
,显示查询需要的时间。另一项要考虑的是 Rows_sent
和 Rows_examined
的数量,因为这些可指这样的情况:其中如果一个查询察看太多行或返回太多行,就会被错误地书写。您可以更深入地钻研如何写查询,即在查询开始处加上 EXPLAIN
,它会返回查询计划,而非结果集,如清单 2 所示。
清单 2. MySQL EXPLAIN
结果
mysql> explain select * from accounts inner join leads on accounts.id = leads.account_id;+----+-------------+----------+--------+--------------------------+---------+---| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+----------+--------+--------------------------+---------+--------| 1 | SIMPLE | leads | ALL | idx_leads_acct_del | NULL | NULL | NULL | 200 | || 1 | SIMPLE | accounts | eq_ref | PRIMARY,idx_accnt_id_del | PRIMARY | 108 | sugarcrm.leads.account_id | 1 | |+----+-------------+----------+--------+--------------------------+---------+---------2 rows in set (0.00 sec) |
M