MySQL JOIN和PHP foreach循环的区别

3

我有一个优化MySQL查询的问题,但目前它需要太长时间才能获取仅限于500条记录的简单结果。

我的查询如下:

SELECT ou.*, gr.accepted, gr.value 
FROM offer_usermeta ou 
LEFT JOIN gateway_requests AS gr ON ou.customer_id = gr.customer_id 
WHERE ou.customer_id != "" 
AND ou.created >= '2012-10-08 00:00:00' 
AND ou.created <= '2012-10-08 23:59:59' 
ORDER BY ou.created DESC LIMIT 500

这个查询需要花费整整一分钟的时间来迭代大约40,000条记录。如果有任何基于客户ID的网关响应,则需要使用此查询将其拉入数据并且数据看起来正确,但我需要优化建议。我正在考虑只是将数据单独提取出来,然后在必要时进行foreach合并,但我知道那样可能会更慢...
有什么技巧吗?(如果有人知道CodeIgniter中的花式技巧的话)

1
请发布您的表结构。 - G-Nugget
2个回答

2
如果您还没有在“created”列上添加索引,请添加索引。无论您是否仅有500条记录的限制,数据库都必须获取所有记录以执行“order by”并匹配“where”条件。之后尝试。
SELECT ou.*, gr.accepted, gr.value 
FROM offer_usermeta ou 
LEFT JOIN gateway_requests AS gr ON ou.customer_id = gr.customer_id 
WHERE ou.created between '2012-10-08 00:00:00' and '2012-10-08 23:59:59' 
ORDER BY ou.created DESC 
LIMIT 500

“is not null” 出现了错误,而 customer_id 从不为空。 - user815437
它可以在左连接中为 null。这就是你使用ou.customer_id!=“”的原因,对吧?我将where子句更改为 “不是null”。 - juergen d
IS NOT NULL可能不是“正确”的。如果该列为NOT NULL,那么该条件就是无意义的。这取决于该列是否可以为NULL以及用于空值的内容是什么。如果@ark3typ3发布表格结构,将会有所帮助。 - G-Nugget
@G-Nugget:你说得对。ou.customer_id不在连接的表上,而是在第一个表上。在这种情况下,它不能为null。 - juergen d
这个方法是可行的,但在一些基准测试之后,我发现使用 foreach 更快(3秒 vs 54秒)。我不确定为什么会这样,但由于这只是一个低流量的功能,只有管理员和高管才能看到,所以我不太担心对服务器性能产生重大影响...不过我还是会继续优化我的查询,因为我觉得通过一些修改,可以让我实现更快的性能。 - user815437
显示剩余3条评论

0

你应该能够使用between语句,这样更有效率。

AND ou.created between '2012-10-08 00:00:00' AND '2012-10-08 23:59:59'


谢谢你的建议,它虽然只减少了一秒钟的时间,但更易读和友好,我很喜欢。 - user815437

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接