提高 SQL 查询 Select 性能
Improving SQL Query Select Performance
我有一个 SQL 查询从多个表中提取数据。我遇到的唯一问题是查询确实需要很长时间,我想知道是否有办法加快速度。我通过使用 INNER JOIN 而不是 LEFT JOIN 做了一些小改进,但查询速度很慢。
SELECT
clientlist.CRMContactId,
clientlist.ClientAdviser,
COALESCE(NULLIF(clientlist.FirstName, ""), clientlist.CorporateName) AS FirstName,
clientlist.LastName,
clientlist.ServiceStatusName,
FORMAT(t.totalfum, 2) AS "Funds Under Management",
FORMAT(d.totalfci, 2) AS "Total Income",
(SELECT DueDate
FROM tasks
WHERE ClientRef = clientlist.ClientRef
AND `Status` <> "Complete"
ORDER BY DueDate DESC
LIMIT 1) AS NextDate,
(SELECT CompletedDate
FROM tasks
WHERE ClientRef = clientlist.ClientRef
AND `Status` = "Complete"
ORDER BY DueDate DESC
LIMIT 1) AS LastDate
FROM
clientlist
INNER JOIN
(SELECT
plans.ClientId, SUM(plans.CurrentVal) AS totalfum
FROM
plans
GROUP BY
plans.ClientId) t ON clientlist.CRMContactId = t.ClientId
INNER JOIN
(SELECT
adviserfci.ClientId, SUM(adviserfci.Payable) AS totalfci
FROM
adviserfci
WHERE
IncomeType IN ("Renewal Commission", "Ongoing Fee", "Fund Based Commission")
OR (Incometype = "Payaway Received"
AND UnderlyingIncomeType IN ("Renewal", "Ongoing Fee", "Fund Based"))
GROUP BY
adviserfci.ClientId) d ON clientlist.CRMContactId = d.ClientId
WHERE
d.totalfci IS NOT NULL
我还在某处读到解释命令将有助于确定问题,但我不理解响应。
有什么方法可以提高此查询的性能?
首先,您是否为这些 table 创建了索引?
在不知道你的数据结构和你将要在它们中放入什么样的查询负载的情况下很难说,但乍一看我会说这些索引应该提高性能,如果你没有它们还有:
- table 客户列表中的 CRMContactId
- table 计划中的 ClientId
- adviserfci 上的 ClientId(包括 IncomeType 和 Payable)
如果您还没有设置 table 主键,并且从列名来看,它们听起来像是不错的候选键,所以如果可行的话,您可以一石二鸟。
将 d.totalfci IS NOT NULL
的测试折叠到生成它的子查询中,即使它需要在 HAVING
子句中。
添加一些索引
tasks: INDEX(ClientRef, `Status`, DueDate)
plans: INDEX(ClientId, CurrentVal)
adviserfci: INDEX(ClientId)
我有一个 SQL 查询从多个表中提取数据。我遇到的唯一问题是查询确实需要很长时间,我想知道是否有办法加快速度。我通过使用 INNER JOIN 而不是 LEFT JOIN 做了一些小改进,但查询速度很慢。
SELECT
clientlist.CRMContactId,
clientlist.ClientAdviser,
COALESCE(NULLIF(clientlist.FirstName, ""), clientlist.CorporateName) AS FirstName,
clientlist.LastName,
clientlist.ServiceStatusName,
FORMAT(t.totalfum, 2) AS "Funds Under Management",
FORMAT(d.totalfci, 2) AS "Total Income",
(SELECT DueDate
FROM tasks
WHERE ClientRef = clientlist.ClientRef
AND `Status` <> "Complete"
ORDER BY DueDate DESC
LIMIT 1) AS NextDate,
(SELECT CompletedDate
FROM tasks
WHERE ClientRef = clientlist.ClientRef
AND `Status` = "Complete"
ORDER BY DueDate DESC
LIMIT 1) AS LastDate
FROM
clientlist
INNER JOIN
(SELECT
plans.ClientId, SUM(plans.CurrentVal) AS totalfum
FROM
plans
GROUP BY
plans.ClientId) t ON clientlist.CRMContactId = t.ClientId
INNER JOIN
(SELECT
adviserfci.ClientId, SUM(adviserfci.Payable) AS totalfci
FROM
adviserfci
WHERE
IncomeType IN ("Renewal Commission", "Ongoing Fee", "Fund Based Commission")
OR (Incometype = "Payaway Received"
AND UnderlyingIncomeType IN ("Renewal", "Ongoing Fee", "Fund Based"))
GROUP BY
adviserfci.ClientId) d ON clientlist.CRMContactId = d.ClientId
WHERE
d.totalfci IS NOT NULL
我还在某处读到解释命令将有助于确定问题,但我不理解响应。
有什么方法可以提高此查询的性能?
首先,您是否为这些 table 创建了索引?
在不知道你的数据结构和你将要在它们中放入什么样的查询负载的情况下很难说,但乍一看我会说这些索引应该提高性能,如果你没有它们还有:
- table 客户列表中的 CRMContactId
- table 计划中的 ClientId
- adviserfci 上的 ClientId(包括 IncomeType 和 Payable)
如果您还没有设置 table 主键,并且从列名来看,它们听起来像是不错的候选键,所以如果可行的话,您可以一石二鸟。
将 d.totalfci IS NOT NULL
的测试折叠到生成它的子查询中,即使它需要在 HAVING
子句中。
添加一些索引
tasks: INDEX(ClientRef, `Status`, DueDate)
plans: INDEX(ClientId, CurrentVal)
adviserfci: INDEX(ClientId)