我生产环境中的 MySQL 查询所花的时间也比我预期的要长得多。所讨论的站点是一个相当大的 Drupal 站点,安装了许多模块。Web 服务器 (Nginx) 和数据库服务器 (mysql) 托管在不同的机器上,通过 100mbps LAN 连接(由 Rackspace 托管)连接。
我在笔记本电脑上运行了完全相同的网站以供开发。显然,在我的笔记本电脑上,Web 服务器和数据库服务器位于同一台机器上。
以下是我的数据库查询时间的结果:
生产:
在 320.33 毫秒内执行了 291 个查询。(主页)
在 999.81 毫秒内执行了 517 个查询。(内容页面)
发展:
在 46.28 毫秒内执行了 316 个查询。(主页)
在 79.09 毫秒内执行了 586 个查询。(内容页面)
从这些结果可以清楚地看到,在我的笔记本电脑上查询 MySQL 数据库所需的时间要短得多,其中 MySQL 服务器与 Web 服务器在同一个数据库上运行。
为什么是这样?!
一个因素肯定是网络延迟。平均而言,从 Web 服务器到数据库服务器的往返行程需要 0.16 毫秒(ping 显示)。这必须添加到每个单个 MySQL 查询中。因此,以上面的内容页面示例为例,其中执行了 517 个查询。仅网络延迟就会使总查询时间增加 82 毫秒。但是,这并不能解释我看到的差异(我的笔记本电脑上为 79 毫秒,而生产机上为 999 毫秒)。
我还应该考虑哪些其他因素?我曾考虑过将 NIC 升级为千兆连接,但显然还涉及其他因素。
我已经运行了 MySQL 性能调优脚本http://www.day32.com/MySQL/它告诉我我的数据库服务器配置得很好(显然比我的笔记本电脑好)。报告的唯一问题是“在 4394 个临时表中,48% 是在磁盘上创建的”。这在两种环境中都是正确的,在生产环境中,我甚至尝试将 max_heap_table_size 和 Current tmp_table_size 增加到 1GB,没有任何变化(我认为这是因为我有一些 BLOB 和 TEXT 列)。
答案1
这是因为如果数据库与前端不在同一台服务器上,则必须对每个查询进行一次往返(可能更多,取决于答案的大小)。ping 同一数据中心的另一台服务器很容易需要 1 毫秒。如果两台服务器位于同一机架上,则时间会少得多,但 1 毫秒是一个很好的经验法则。
这意味着对于~300 个小查询,您应该预计大约需要~300 毫秒,非常接近您所看到的情况。
如果两台服务器位于同一台机器上,则只需在进程之间进行一些上下文切换即可将数据从 DB 进程移动到前端。通常,上下文切换(包括所有典型的刷新)需要约 40us(广义上讲),并且您至少需要其中几个(前端请求数据,DB 读取请求并准备和提供数据,前端读回数据)。所以我预计每个查询大约需要 80us(让我们将其四舍五入为 0.1ms 以使计算更容易)。因此,您可以预期 300 个小查询大约需要 30ms,这也非常接近您所看到的情况。
答案2
很难给你一个明确的答案。我真的不认为网络是瓶颈,除非你的服务器流量真的很大。
您的开发机器和生产服务器上的配置是否完全相同?
您确定生产服务器上的所有索引都已成功创建吗?
这可能是生产服务器中的数据量。我的意思是,要比较生产机器和开发机器之间的结果,表中的行数应该相同,是这样吗?
您是否使用相同的安装文件在开发机器和生产服务器上设置 MySQL?我的意思是,您的开发机器和生产机器上的 MySQL 版本是否相同?它们适用于相同的操作系统吗?也是 32 位还是 64 位?可能是服务器上安装的 MySQL 版本存在错误。
可能性是无穷无尽的,如果没有更多的细节就很难给你一个有用的答案。
答案3
您是否启用了查询缓存?查看以下输出:
SHOW VARIABLES LIKE 'query_cache_size';
如果大于零,则打开。这将对 MySQL 支持的网站的性能产生很大影响,尽管我不确定这是否与您的特定问题有关。
我认为没有任何方法可以捕获查询集并从 MySQL 数据库服务器上的登录运行它们,以查看那里的情况是否不同?
另一个可能的问题是,如果您没有进行会话缓存,则每次进行数据库调用时都会打开一个新会话。您知道您是否进行了会话缓存吗?每次调用都打开一个新会话可能会在网络上产生高昂的成本。
答案4
我会做什么来确定瓶颈在哪里:我会对查询进行分析:http://dev.mysql.com/doc/refman/5.0/en/show-profiles.html
如果数字远低于您在 Web 服务器上运行的相同查询所看到的数字,那么这是一个“传输”问题。(Rackspace 网络延迟、交换机配置、返回带有TEXT
/BLOB
字段的大量数据 (SELECT *) 等)
如果数字几乎相似,则必须优化查询并改进配置文件。以下链接可能对您有帮助:https://stackoverflow.com/questions/1191067/how-to-test-mysql-query-speed-with-less-inconsistencies/1191506#1191506
顺便说一句,当我的服务器从 100Mbs 增加到 1Gb 时,性能的提升是惊人的!