我正在尝试在此测试脚本上优化我的 PHP<>MySQL:
<?
for($i=0;$i<100;$i++)//Iterations count
$res.= var_dump(loadRow("select body_ru from articles where id>$i*50 limit 100"));
print_r($res);
?>
我有 APC,并且文章表在 id 上有一个索引。此外,所有这些查询都在访问查询缓存,所以如果 MySQL 性能很好的话。
但是当我使用 ab -c 10 -t 10 来测试这个脚本时,我得到:
100 次迭代:~100req/sec(~10'000 MySQL 查询每秒)
5 次迭代:~200req/sec
1 次迭代:~380req/秒
0 次迭代:~580req/sec
我试图在 PHP 中禁用持久连接——它让它变慢了一点。那么,如果 MySQL 不限制性能,我怎样才能让它工作得更快呢?
所以这看起来像建立连接或其他东西需要太多时间......
mysql_pconnect 会更快,但是,正在消失(我不相信它甚至被 mysqli 支持)。持久连接消除了连接/拆卸时间。
你的mysql是通过TCP还是socket连接的?如果是 TCP,是否打开了压缩或 SSL?当您期望较大的响应时,压缩是好的,但是,对于较小的响应,您会花费更多的 cpu 时间在两侧进行压缩/解压缩。您希望大约 99% 的时间都使用压缩。php 和 mysql 之间的 SSL 连接将是明确的性能障碍。
如果您通过 TCP 连接,mysql 中的 skip-name-resolve 会加快速度。然后需要在您的授权中使用 IP 而不是域名。
但是,您对这些查询可能在缓存中的假设取决于您的缓存有多大以及您的结果集有多大。如果您的查询平均每个结果集为 400k(假设文章长度为 4k),那么您至少需要一个 40mb 的查询缓存来缓存内容。如果您发送回任何整数字段,请记住 libmysqlclient 库将整数转换为 ascii,然后 php 在收到结果时必须将其转换为任何数据类型。
mysql_fetch_assoc 比 mysql_fetch_row 稍微慢一些,但还不足以让您发现将代码转换为使用它是值得的。
我相信您可能遇到了与 mysql 服务器的连接问题。如果您使用的是 TCP,您需要进行一些更改。如果您使用的是套接字连接,那么您可能无法从中调整太多性能。
@pQd,根据我的经验,我发现索引查询的限制子句上的查询优化器将从索引中得到回答,并且使用范围索引不会对结果产生太大影响。范围查询也不会考虑后来删除的文章 ID,这会导致分页。如果删除其中 20 篇文章,第 100-150 条将返回 30 行,这可能无法正确填满您的页面。数据表示的限制条款通常是正确的方法。只有当您使用 sql_count_rows 时,mysql 才会执行整个查询,这是另一个有用的分页工具。您要确保从索引中回答这些查询以防止表扫描。
是的,我知道你说 mysql 不是限制因素,但无论如何试试这个:
mysql以奇怪的方式处理限制......无论如何它都会生成整个结果,然后只向客户端发送前n行。所以从上下边界过滤 id 。稍微更多stackoverflow-ish部分:
该代码与您的代码不是 100% 等效-在您的情况下,您一直在收到重叠的块。
loadRow 里面有什么 - 它使用 mysqli 吗?mysql?像adodb这样的抽象?如果您调整性能,请跳过类似 adodb 的库。
另外 - 我会相信比查询缓存更多的 innodb_buffer_pool。
请让我们知道提议的更改如何影响性能。