【问题标题】:MySQL JOIN vs PHP foreach loopMySQL JOIN 与 PHP foreach 循环
【发布时间】:2012-10-15 19:08:23
【问题描述】:

我在优化 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 提取网关响应(如果有),并且此查询的数据看起来正确,但我需要优化提示。我正在考虑单独提取数据并在必要时将它们组合在一起,但我知道这可能会慢得多......

有什么建议吗? (如果有人知道其中的花哨技巧,我正在使用 codeigniter)

【问题讨论】:

  • 请发布您的表格结构。

标签: php mysql codeigniter indexing


【解决方案1】:

如果您还没有,请在 created 列上添加索引。数据库必须获取所有记录以执行 order by 并匹配 where 条件,无论您是否拥有只有 500 条记录的 limit。之后尝试

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

【讨论】:

  • "not is null" 给出一个错误并且 customer_id 永远不会为空。 EDIT 它是“不为空”,反之则出错。
  • 它可以是null 中的left join。这就是你使用ou.customer_id != "" 的原因,对吧?我将 where 子句更改为 is not null
  • IS NOT NULL 可能不是“正确的”。如果列是NOT NULL,则该条件毫无意义。这取决于该列是否可以是 NULL 以及用于空值的内容。如果@ark3typ3 发布表格的结构会有所帮助。
  • @G-Nugget:你是对的。 ou.customer_id 不在连接表上,而是在第一个表上。在这种情况下,它不能为空。
  • 这行得通,但经过一些基准测试后,我确实使用 foreach 获得了更快的结果(3 秒对 54 秒)。我不确定那是怎么回事,但由于这是一个只有管理员和高管才能看到的低流量功能,所以我不太担心对服务器性能的巨大影响......我会继续优化我的查询,因为我觉得一些修改可能会导致我实施的结构的性能更快
【解决方案2】:

你应该可以做一个 between 语句,这样效率更高。

AND ou.created 介于“2012-10-08 00:00:00”和“2012-10-08 23:59:59”之间

【讨论】:

  • 感谢您的提示,它节省了一秒钟,但它更具可读性和友好性,所以我喜欢它。
猜你喜欢
  • 1970-01-01
  • 2016-10-25
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 2018-12-24
  • 2011-01-05
  • 2016-09-02
  • 2013-04-26
相关资源
最近更新 更多