我想根据我用PHP代码编写的复杂查询从MySQL中检索一些数据。检索数据的速度非常慢。我怎么解决这个问题?有没有办法改善性能?我正在使用WAMP服务器。 我需要在PHP中完成所有操作。事实上,我希望连接来自同一用户的所有推文,并使用他/她的名字将其推送到数组中。 我使用$ twitter数组来存储twitters的名称,并且我在数据集中连接来自同一用户的所有推文,如下所示:
$number_of_twitters=sizeof($twitters);
for($i=0;$i $number_of_twitters;$i++){
$getTweetsQuery="SELECT Tweets FROM tweettable WHERE Name='$twitters[$i]'";
$tweets=mysql_query($getTweetsQuery);
$tweetString="";
while($tweetsRow=mysql_fetch_array($tweets)){
$tweetString .= $tweetsRow[0]." ";
}
那为什么表演太重了?
答案 0 :(得分:3)
捕获应用程序发出的SQL。如果您无法在应用程序中执行此操作,则可以启用MySQL常规日志,但这将记录所有会话中的所有sql语句。
使用EXPLAIN
查看生成的访问计划。
这种下意识的快速回答是"添加索引",但关键是确定最合适的 正在运行的查询的索引,并删除不必要的索引。
您的查询中可能存在阻止最佳性能的谓词,例如,在函数中包装列会禁止MySQL执行索引范围扫描和索引搜索。
另一个下意识的快速回答是为实例添加内存,以便缓存更多的块,以减少物理I / O.
MyISAM存储引擎采用表级锁,即使对于SELECT语句也是如此,并且会导致并发性。 InnoDB在并发查询方面表现更好。
<强>更新强>
此查询最合适的索引:
SELECT Tweets FROM tweettable WHERE Name='$twitters[$i]'
将是一个覆盖指数:
... ON tweetable (Name, Tweets)
EXPLAIN将显示当前的执行计划:
EXPLAIN SELECT Tweets FROM tweettable WHERE Name='foo'
理想情况下,我们希望解释输出显示&#39;使用索引&#39;。但至少,我们希望看到MySQL通过索引访问行,因此它不必对表中的每一行进行完全扫描,以查看该行是否满足谓词。
此查询似乎也处于循环中。使用单个语句检索一组行通常更有效,而不是运行多个语句。 (当每次执行从非常大的表中提取少量行时,情况尤其如此,并且查询正在对表进行全面扫描。)
SELECT t.Tweets
FROM tweetable t
WHERE t.Name = 'fee'
OR t.Name = 'fi'
OR t.Name = 'fo'
OR t.Name = 'fum'
ORDER BY t.Name
或同等的:
SELECT t.Tweets
FROM tweetable t
WHERE t.Name IN ('fee','fi','fo','fum')
ORDER BY t.Name
MySQL还有一个你可能会觉得有用的GROUP_CONCAT函数。
SELECT GROUP_CONCAT(t.Tweets ORDER BY t.Name SEPARATOR ' ') AS tweetstring
FROM tweetable t
WHERE t.Name IN ('fee','fi','fo','fum')
注意 GROUP_CONCAT返回的字符串长度受group_concat_max_len
和max_allowed_packet
变量的限制。