繁体   English   中英

没有where子句的M​​ySQL查询运行非常慢(实际上从不提供输出)

[英]MySql query runs very slow(actually never gives output) without where clause

我有一个mysql查询,当我使用where子句时它运行良好,但是当我不使用where子句时,它消失了,并且从不给出输出,最后也没有超时。 实际上,我已经使用Explain命令检查查询的性能,并且在两种情况下, Explain给出的连接使用的行数均相同。 我已经附上了Explain命令获得的输出图像。 下面是查询。 我不知道这里出了什么问题。 非常感谢您的帮助。 谢谢。

 SELECT 
        MCI.CLIENT_ID AS CLIENT_ID, MCI.NAME AS CLIENT_NAME, MCI.PRIMARY_CONTACT AS CLIENT_PRIMARY_CONTACT, 
        MCI.ADDED_BY AS SP_ID, CONCAT(MUD_SP.FIRST_NAME, ' ', MUD_SP.LAST_NAME) AS SP_NAME, 
        MCI.FK_PROSPECT_ID AS PROSPECT_ID, MCI.DATE_ADDED AS ADDED_ON,
        (SELECT GROUP_CONCAT(LT.TAG_TEXT SEPARATOR ', ') 
            FROM LK_TAG LT
            INNER JOIN M_OBJECT_TAG_MAPPING MOTM
            ON LT.PK_ID = MOTM.FK_TAG_ID
            WHERE MOTM.FK_OBJECT_ID = MCI.FK_PROSPECT_ID
                AND MOTM.OBJECT_TYPE = 1
                AND MOTM.IS_ACTIVE = 1
        ) AS TAGS,
        IFNULL(SUM(GET_DIGITS(MMR.RCP_AMOUNT)), 0) AS REVENUE_SO_FAR,
        IFNULL(SUM(GET_DIGITS(MMR.RCP_RUPEES)), 0) AS REVENUE_INR,
        COUNT(DISTINCT PMI_MONTHLY.PROJECT_ID) AS MONTHLY,
        COUNT(DISTINCT PMI_FIXED.PROJECT_ID) AS FIXED,
        COUNT(DISTINCT PMI_HOURLY.PROJECT_ID) AS HOURLY,
        COUNT(DISTINCT PMI_ANNUAL.PROJECT_ID) AS ANNUAL,
        COUNT(DISTINCT PMI_CURRENTLY_RUNNING.PROJECT_ID) AS CURRENTLY_RUNNING_PROJECTS,
        COUNT(DISTINCT PMI_YET_TO_START.PROJECT_ID) AS YET_TO_START_PROJECTS,
        COUNT(DISTINCT PMI_TECH_SALES_CLOSED.PROJECT_ID) AS TECH_SALES_CLOSED_PROJECTS
    FROM 
        M_CLIENT_INFO MCI
        INNER JOIN M_USER_DETAILS MUD_SP
            ON MCI.ADDED_BY = MUD_SP.PK_ID
        LEFT OUTER JOIN M_MONTH_RECEIPT MMR
                ON MMR.CLIENT_ID = MCI.CLIENT_ID
        LEFT OUTER JOIN M_PROJECT_INFO PMI_FIXED
                ON PMI_FIXED.CLIENT_ID =  MCI.CLIENT_ID AND PMI_FIXED.PROJECT_TYPE = 1
        LEFT OUTER JOIN M_PROJECT_INFO PMI_MONTHLY
                ON PMI_MONTHLY.CLIENT_ID =  MCI.CLIENT_ID AND PMI_MONTHLY.PROJECT_TYPE = 2
        LEFT OUTER JOIN M_PROJECT_INFO PMI_HOURLY
                ON PMI_HOURLY.CLIENT_ID =  MCI.CLIENT_ID AND PMI_HOURLY.PROJECT_TYPE = 3
        LEFT OUTER JOIN M_PROJECT_INFO PMI_ANNUAL
                ON PMI_ANNUAL.CLIENT_ID =  MCI.CLIENT_ID AND PMI_ANNUAL.PROJECT_TYPE = 4
        LEFT OUTER JOIN M_PROJECT_INFO PMI_CURRENTLY_RUNNING
                ON PMI_CURRENTLY_RUNNING.CLIENT_ID =  MCI.CLIENT_ID AND PMI_CURRENTLY_RUNNING.STATUS = 4
        LEFT OUTER JOIN M_PROJECT_INFO PMI_YET_TO_START
                ON PMI_YET_TO_START.CLIENT_ID =  MCI.CLIENT_ID AND PMI_YET_TO_START.STATUS < 4
        LEFT OUTER JOIN M_PROJECT_INFO PMI_TECH_SALES_CLOSED
                ON PMI_TECH_SALES_CLOSED.CLIENT_ID =  MCI.CLIENT_ID AND PMI_TECH_SALES_CLOSED.STATUS > 4
               WHERE YEAR(MCI.DATE_ADDED) = '2012'
                GROUP BY MCI.CLIENT_ID ORDER BY CLIENT_NAME ASC  

在此处输入图片说明

是的,正如许多人所说的,关键是当您拥有where子句时,mysql引擎会过滤表M_CLIENT_INFO -可能是动态地-。

与删除where子句类似的结果是添加以下where子句:

where 1 = 1

您还会看到性能下降,因为mysql会尝试获取所有数据。

从select中删除where子句和所有列,并添加计数以查看获得的记录数。 如果合理,最多说10k,然后执行以下操作,

  1. 放回与M_CLIENT_INFO相关的选择列

  2. 不包括嵌套的一个“ TAGS”

  3. 删除所有联接

  4. 在不使用where子句的情况下运行查询,并逐渐包含联接

这样,您就可以找出造成超时的时间。

我会尝试以下。 首先,MySQL有一个关键字“ STRAIGHT_JOIN”,它告诉优化器按照您指定的表顺序进行查询。 由于所有左联接都是与子相关的(例如查找表),因此您不希望MySQL尝试将其中之一解释为查询的主要基础。

SELECT STRAIGHT_JOIN ...其余查询。

接下来,您的M_PROJECT_INFO表不知道有多少数据列,但是您似乎只专注于DISTINCT聚合中的几列。 我将确保您在这些元素上具有覆盖索引,以通过以下索引来帮助查询

(Client_ID,Project_Type,Status,Project_ID)

这样,引擎可以应用条件并从索引中获取唯一的内容,而不必回到原始数据页面进行查询。

第三,您的M_CLIENT_INFO表。 确保在两个条件上都有一个索引,并按AND和Order By进行分组,并通过别名“ CLIENT_NAME”将订单更改为SQL表的实际列,以使其与索引匹配

(添加日期,客户ID, Name

我在“滴答”中有一个“名称”,因为它也是一个保留字,可以帮助澄清该列,而不是关键字。

接下来,WHERE子句。 每当将函数应用于索引列名时,它都无法发挥最大的作用,尤其是在日期/时间字段上……您可能需要将where子句更改为

WHERE MCI.Date_在“ 2012-01-01”和“ 2012-12-31 23:59:59”之间添加

因此BETWEEN范围会显示整个年份,因此可以更好地利用该指数。

最后,如果上述方法没有帮助,我会考虑将您的查询拆分一些。 TAGS的GROUP_CONCACT内联选择可能对您来说是个杀手er。 您可能希望首先将所有不同的元素用于每个客户的分组,然后获取这些详细信息。

select
      PQ.*,
      group_concat(...) tags
   from
      ( the entire primary part of the query ) as PQ
         Left join yourGroupConcatTableBasis on key columns

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM