SELECT IFNULL( c.compId, '1' ) compId, c.compShortName, IFNULL( c.compCompID, '' ) compCompID, IFNULL( c.compName, '未绑定单位' ) compName, COUNT( CASE WHEN checkType = '1' THEN 1 END ) AS jsCount, COUNT( CASE WHEN checkType = '0' THEN 1 END ) AS count, d.compName compCompName FROM checkinfo b LEFT JOIN companyinfo c ON b.checkCompanyId = c.compId LEFT JOIN companyinfo d ON c.compCompId = d.compId WHERE b.STATUS = '1' -- AND c.compName != '未绑定单位' GROUP BY c.compId, checkType ORDER BY count( checkId ) DESC 怎样优化
针对您提供的 SQL 查询,以下是一些优化建议:
-
避免使用 IFNULL 函数:在您的查询中,
IFNULL
函数被用来处理可能的NULL
值。然而,如果compId
和compCompID
列的默认值就是'1'
和空字符串''
,那么您可以直接使用这些值而不需要IFNULL
函数。这可以简化查询并可能提高性能2458。 -
使用 COUNT(1) 替代 COUNT(字段名):在
GROUP BY
子句中,如果不需要对特定字段进行计数,使用COUNT(1)
通常比COUNT(字段名)
更快,因为它不需要检查字段值是否为NULL
9。 -
避免重复的 COUNT 函数:在您的查询中,您使用了两个
COUNT
函数来分别计算checkType
为 '1' 和 '0' 的数量。这可以通过使用SUM
函数和CASE
表达式来合并,从而减少函数调用次数67。 -
考虑使用 JOIN 条件的优化:在您的查询中,使用了两次
LEFT JOIN
来连接companyinfo
表。如果compCompId
列经常为NULL
,这可能会导致大量的空连接,从而影响查询性能。您可以考虑使用更有效的连接条件或索引来优化这部分9。 -
使用索引:确保
b.checkCompanyId
和c.compId
以及c.compCompId
和d.compId
上有适当的索引,这可以加快连接操作的速度9。 -
考虑查询逻辑:您在
WHERE
子句中使用了b.STATUS = '1'
,但在注释中有一个条件AND c.compName != '未绑定单位'
被注释掉了。如果这个条件是必要的,应该取消注释并包含在查询中,以避免不必要的数据处理。 -
优化 ORDER BY 子句:在
ORDER BY
子句中,您使用了count( checkId ) DESC
。如果checkId
列不是索引列,这可能会导致一个全表扫描来计算行数。如果可能,考虑使用其他方式来排序,或者确保checkId
列上有索引。 -
避免使用星号 (*) 在 SELECT 子句中:在您的查询中,没有使用星号 (*) 来选择所有列,这是一个好习惯,因为它有助于减少数据传输量。确保在实际使用中也遵循这一原则。
根据上述建议,您的查询可以被重写为以下形式:
SELECT
c.compId,
c.compShortName,
c.compCompID,
COALESCE(c.compName, '未绑定单位') AS compName,
SUM(CASE WHEN checkType = '1' THEN 1 ELSE 0 END) AS jsCount,
SUM(CASE WHEN checkType = '0' THEN 1 ELSE 0 END) AS count,
d.compName AS compCompName
FROM
checkinfo b
LEFT JOIN companyinfo c ON b.checkCompanyId = c.compId
LEFT JOIN companyinfo d ON c.compCompId = d.compId
WHERE
b.STATUS = '1'
GROUP BY
c.compId,
checkType
ORDER BY
COUNT(*) DESC;
请注意,这些只是基于您提供的查询和一般 SQL 优化原则的建议。实际优化效果可能需要根据具体的数据库架构、数据分布和查询执行计划来评估。