具有三个未索引的联合表和一个左连接的MySQL查询会使数据库负担过重

具有三个未索引的联合表和一个左连接的MySQL查询会使数据库负担过重,mysql,sql,performance,left-join,union-all,Mysql,Sql,Performance,Left Join,Union All,我有一个相当复杂的SQL查询,我不知道如何做得不那么复杂。如果我尝试运行它,它会使数据库负担过重。如果我把它简化一点,我可以执行它,但这需要很多时间。 我确信有更有效的方法来编写这个查询,但我不知道如何编写。如果有人能把我引向正确的方向,我会非常高兴的 SELECT master.C_MASTER_ID, master.C_MASTER_SUMMARY, master.C_MASTER_START, master.C_MASTER_END,

我有一个相当复杂的SQL查询,我不知道如何做得不那么复杂。如果我尝试运行它,它会使数据库负担过重。如果我把它简化一点,我可以执行它,但这需要很多时间。 我确信有更有效的方法来编写这个查询,但我不知道如何编写。如果有人能把我引向正确的方向,我会非常高兴的

SELECT master.C_MASTER_ID,
       master.C_MASTER_SUMMARY,
       master.C_MASTER_START,
       master.C_MASTER_END,
       master.C_MASTER_LEVEL,
       master.C_MASTER_SOURCE,
       NULL AS EVT_HAS_Z,
       master.C_MASTER_NOTES,
       master.C_MASTER_SERVICE,
       c2c.CER_CUSTOMER
FROM `C_MASTER` master
LEFT JOIN `c2customer` c2c ON c2c.CER_ID = master.C_MASTER_ID
WHERE 
  master.C_MASTER_END >= NOW()
  AND master.C_MASTER_START >= DATE_SUB(NOW(), INTERVAL 21 DAY)

UNION ALL

SELECT EVT_ID AS C_MASTER_ID,
       EVT_SUMMARY,
       EVT_START_DATE,
       EVT_END_DATE,
       NULL AS C_MASTER_LEVEL,
       NULL AS C_MASTER_SOURCE,
       EVT_HAS_Z,
       NULL AS C_MASTER_NOTES,
       NULL AS C_MASTER_SERVICE,
       NULL AS CER_CUSTOMER
FROM C_event
WHERE EVT_end_date >= NOW()

UNION ALL

SELECT 'WHISPER' AS C_MASTER_CHANGE_ID,
       WISP_SUMMARY,
       WISP_START_DATE,
       WISP_END_DATE,
       NULL AS C_MASTER_LEVEL,
       NULL AS C_MASTER_SOURCE,
       NULL AS EVT_HAS_Z,
       NULL AS C_MASTER_NOTES,
       NULL AS C_MASTER_SERVICE,
       NULL AS CER_CUSTOMER
FROM C_wispering
WHERE WISP_END_DATE >= NOW()

这是我的查询的一个稍微简化的版本,因为其他情况下,请求帮助的帖子很难管理

您应该分别运行每个查询,以确定导致性能问题的原因。您还可以查看“解释”以查看计划

首先,我可以说第一个查询将受益于
c\u master(c\u master\u START,c\u master\u ID)
c2customer(CER\u ID,CER\u CUSTOMER)
上的索引


第二个将受益于
C\u事件(EVT\u end\u date)
的索引。第三个:
C\u wispering(WISP\u END\u DATE)

您从数据库中得到的行数大约是多少?你的索引是什么样的?在哪些字段上等等?@Tikkes大约有6000行。我只有C_MASTER_ID和CER_ID索引。我不愿意使用索引,因为我对它不太了解。索引更多字段有什么缺点吗?在这种情况下,你应该考虑阅读索引。SQL文档在这方面非常丰富,在处理更复杂的数据库时非常有用。正确使用索引可以非常好地提高性能。当然,将索引放在任何东西或任何东西上都有缺点,这就是为什么您应该将索引放在搜索查询中经常需要或使用的字段上,而且组合索引在大多数情况下都可以对您有利@蒂克斯:非常感谢!看来我再也绕不开这个话题了。你会说查询看起来没问题吗?你会这么认为-当然不知道数据库-但你为什么这么做:
master.C_master_START>=NOW()和master.C_master_START>=DATE_SUB(NOW(),INTERVAL 21 DAY)
?既然您的第二个检查已经声明它应该在过去21天之后,那么为什么首先检查<代码> NOW()(<代码>?SIDNENOTER),但是,当在日期时间上放置一个索引时,考虑不包括毫秒/秒/分钟并且以小时为目标而不是减少负载是明智的。关于性能的更多信息也可以在上找到,非常感谢您的回答!!到目前为止,我只有CER_ID和C_MASTER_ID索引。我一直不愿意使用索引,只是因为我对它了解不多:/-索引更多字段会有什么负面影响,在索引您建议的字段时会有什么风险,还是我可以直接索引?(我在DB上有一个每日写入过程,在我索引C_MASTER_ID和CER_ID时,到目前为止还没有涉及到这个过程,但我担心如果我再索引,它会慢很多)@tikkes恕我直言,DATETIME索引肯定是处理这类事情的最佳方法。您提供的链接中的公认答案包含一些关于日期时间索引复杂性的严重错误信息。@OllieJones您是否知道,如果我对日期时间进行索引,是否会显著降低大型日常写入操作的速度?如果您有6千兆行,可能会,但可能不会。有600万美元,当然不是。有6000行,你甚至不会注意到。MySQL和其他RDMS系统是为处理非常大的卷而构建的。