我有一个包含大量行的 MySql 表。我正在做一个简单的请求,它工作得非常快。当请求本身只需要 0.3 秒时,向客户端获取数据的唯一问题是大约 150 秒非常慢。
我在客户端和 Amazon EC2 MySql 实例上使用 php 5.3 + ZendFramework。PHP 代码和 MySql 位于不同的服务器上。
谁能告诉我如何提高数据获取速度?
我有一个包含大量行的 MySql 表。我正在做一个简单的请求,它工作得非常快。当请求本身只需要 0.3 秒时,向客户端获取数据的唯一问题是大约 150 秒非常慢。
我在客户端和 Amazon EC2 MySql 实例上使用 php 5.3 + ZendFramework。PHP 代码和 MySql 位于不同的服务器上。
谁能告诉我如何提高数据获取速度?
根据您最终提供的正在运行的查询的评论。
select * from table
你还说你有“大量的行”。这应该足够简单,您可以理解为什么需要永远传输到查询数据库的框。
而且,仅仅因为您的查询运行速度很快,您仍然必须处理网络限制。另外,假设您实际收到结果后,如果您使用的是 ORM,您可能会发现结果集的水合会增加您的请求的复杂性和时间。
总的来说,你自己回答了这个问题。不要select * from table
在桌子“巨大”的地方做。
您应该考虑为查询添加限制和偏移量,并且只选择您实际需要的行。
此外,“巨大”是非常主观的。对我来说,一张大表大约有 1000 万行。但对于其他人来说,1000 万是非常小的。我什至不想在一张巨大的桌子上加上一个数字。
缓慢是因为您从表中检索所有数据,并且由于您的数据库和网站有两个不同的服务器,所有需要通过网络传输的数据都会引入额外的缓慢。
如果你问为什么在客户端运行会更快,那是因为大多数 sql 客户端会自动增加行数限制。
正如所有评论所说:您必须提供更多信息才能获得准确(或至少不那么模糊)的答案。但是对于您编写的每个查询,您应该牢记一些经验法则:
SELECT *
尽可能避免,尤其是像SELECT COUNT(*)
,只选择您感兴趣的那些字段。JOIN
. 好的JOIN
可以提高性能,通常非常显着。EXPLAIN EXTENDED
,避免 MySQL 必须在磁盘上创建临时表的情况EXPLAIN
,还要检查隐式CAST
' 或COLLATION
转换。与 PHP 不同,anUNSIGNED INTEGER
与VARCHAR
. 认为它$x = 123;
后面if ($x === '123')
是错误的:一个字符串!==一个int ...MEDIUMTEXT
),因为它们总是会导致磁盘访问LIKE
,尤其是在使用通配符 ( x LIKE 'y%z'
)时%
不是唯一的通配符:_
是单个字符的小丑EXPLAIN
,EXPLAIN
再EXPLAIN
一次……LIMIT
- “巨大”数据集的结果是必须的。如果您要获取大量数据,您将如何处理它们?我无法想象所有数据都将作为一个大块发送给客户端的情况,是吗?