簡體   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