缓慢的 SQL 查询会耗尽 CPU

发布于 2024-11-09 22:03:13 字数 1234 浏览 4 评论 0原文

我继承了一个要照顾的站点,并且遇到了 SQL 查询问题,当作业在该站点上运行时,该查询会耗尽 CPU。

不幸的是,我是一名前端开发人员,虽然我可以使用简单的 sql,但这对我来说太复杂了。问题似乎出在第二个 EXISTS 及其与主查询的连接中。

这是代码,它应该收集项目 ID 列表并发送给公司。

这个查询有什么明显的错误吗?

SELECT mc.id AS company_id,
       mi.id AS item_id,
       EXISTS ( 
        SELECT 1 
         FROM mysite AS m2
         JOIN mysite_order AS mo2 
           ON m2.mysite_order_id = mo2.id 
        WHERE mo2.mysite_item_id = mo.mysite_item_id 
              AND m2.company_email_sent = 'Yes'
       ) AS email_sent_before, 
       m.id AS mysite_id,
       m.mysite_code_prefix,
       m.mysite_code_suffix
  FROM mysite_company AS mc
  JOIN mysite_item AS mi
    ON mc.id = mi.company_id 
  JOIN mysite_order AS mo 
    ON mi.id = mo.mysite_item_id
  JOIN mysite AS m
    ON mo.id = m.mysite_order_id
 WHERE mi.avail_end_date <= CURDATE()
   AND EXISTS ( 
           SELECT 1
             FROM mysite AS m3
             JOIN mysite_order AS mo3
               ON m3.mysite_order_id = mo3.id
            WHERE mo3.mysite_item_id = mo.mysite_item_id 
              AND m3.company_email_sent = 'No' )
ORDER BY company_id ASC, item_id ASC, m.mysite_code_prefix ASC,
            m.mysite_code_suffix ASC
LIMIT 1

I've inherited a site to look after and have a problem with an sql query which is maxing out CPU when the job runs on the site.

Unfortunately, I'm a front end developer and although I'm okay with simple sql this is too complex for me. The problem appears to be in the second EXISTS and its connection with the main query.

Here's the code, it should gather a list of item IDs to send to a company.

Is there anything obviously wrong with this query?

SELECT mc.id AS company_id,
       mi.id AS item_id,
       EXISTS ( 
        SELECT 1 
         FROM mysite AS m2
         JOIN mysite_order AS mo2 
           ON m2.mysite_order_id = mo2.id 
        WHERE mo2.mysite_item_id = mo.mysite_item_id 
              AND m2.company_email_sent = 'Yes'
       ) AS email_sent_before, 
       m.id AS mysite_id,
       m.mysite_code_prefix,
       m.mysite_code_suffix
  FROM mysite_company AS mc
  JOIN mysite_item AS mi
    ON mc.id = mi.company_id 
  JOIN mysite_order AS mo 
    ON mi.id = mo.mysite_item_id
  JOIN mysite AS m
    ON mo.id = m.mysite_order_id
 WHERE mi.avail_end_date <= CURDATE()
   AND EXISTS ( 
           SELECT 1
             FROM mysite AS m3
             JOIN mysite_order AS mo3
               ON m3.mysite_order_id = mo3.id
            WHERE mo3.mysite_item_id = mo.mysite_item_id 
              AND m3.company_email_sent = 'No' )
ORDER BY company_id ASC, item_id ASC, m.mysite_code_prefix ASC,
            m.mysite_code_suffix ASC
LIMIT 1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

攒眉千度 2024-11-16 22:03:13

如何使用这样的内联子查询:

...
    ( SELECT m2.company_email_sent, COUNT(m2.company_email_sent)
    FROM mysite AS m2
    JOIN mysite_order AS mo2
    ON m2.mysite_order_id = mo2.id
    WHERE mo2.mysite_item_id = mo.mysite_item_id 
    AND m2.company_email_sent IN ( 'Yes', 'No' )
    GROUP BY m2.company_email_sent ) email_status
...

然后您可以加入该内联子查询,并查找 COUNT 是否为 0,作为执行这两个单独的 EXISTS 子查询的替代方法。

另外 - 我在这里对业务逻辑做出假设 - 您难道不希望在子查询中加入 mysite_company 吗?即您关心有关相关商品的电子邮件是否已发送给下订单的客户?目前,子查询中没有任何内容与外部查询中的 mysite_customer 相关。

How about using an inline subquery like this:

...
    ( SELECT m2.company_email_sent, COUNT(m2.company_email_sent)
    FROM mysite AS m2
    JOIN mysite_order AS mo2
    ON m2.mysite_order_id = mo2.id
    WHERE mo2.mysite_item_id = mo.mysite_item_id 
    AND m2.company_email_sent IN ( 'Yes', 'No' )
    GROUP BY m2.company_email_sent ) email_status
...

You could then join to that inline subquery, and look for whether or not COUNT is 0, as an alternative to doing those two separate EXISTS subqueries.

Also - and I'm making assumptions about the business logic here - wouldn't you expect to have a join to mysite_company within the subquery? i.e. you care about whether an email about the item in question has been sent to the customer who is making the order? At the moment there's nothing in the subqueries that correlates to the mysite_customer in the outer query.

困倦 2024-11-16 22:03:13

最大的问题是第二个 exists()

根据您要查找的内容,可以将其替换为 mo.company_email_sent = 'No' 或 join 语句。

更理想的是,您希望将该 exists() 语句的值存储在索引字段中。它可以使用触发器或使用应用程序级代码进行设置。

The big issue is the second exists().

Depending on what you're looking for, it could be replaced with mo.company_email_sent = 'No' or a join statement.

Even more ideally, you'd want to store the value of that exists() statement in an indexed field. It could be set using a trigger or using app-level code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文