Mysql

為什麼此查詢的 Group by 和 Have 子句非常慢?

  • March 4, 2018

我有這個查詢,當對 100K 行執行時,需要永遠導致我的系統具有 2 GB Ram 和標準 MySQL 安裝。

現在在我的數據庫中,我有兩個表,chitentry 和 chitentrygroup。兩者都包含超過 100K 行。當我執行以下查詢時,結果始終處於掛起狀態,我沒有得到任何輸出並且查詢繼續執行。

   SELECT  SQL_CALC_FOUND_ROWS  chitentrygroupid, 
                      chitentrygroupdate, 
                      chitentryno, 
                      chitbookno, 
                      chitamount, 
                      entryamount, 
                      entryweight, 
                      employeename, 
                      accountname, 
                      rate, 
                      monthentry 
            FROM   (SELECT chitentrygroup.chitentrygroupid, 
          chitentrygroup.chitentrygroupdate, 
          chitentry.chitentryno, 
          chitentry.chitbookno, 
          Round(( chitentry.chitamount ), 0) AS chitamount, 
          chitentry.entryamount, 
          chitentry.entryweight, 
          employee.employeename, 
          account.accountname, 
          chitentry.rate, 
          chitentry.monthentry 
   FROM   chitentrygroup 
          LEFT OUTER JOIN chitentry 
                       ON chitentry.chitentrygroupid = 
                          chitentrygroup.chitentrygroupid 
          LEFT OUTER JOIN employee 
                       ON employee.employeeid = chitentrygroup.employeeid 
          LEFT OUTER JOIN account 
                       ON account.accountid = chitentrygroup.accountid 
        WHERE  chitentrygroup.status NOT IN ( 0, 3, 8 )  AND chitentrygroup.industryid IN ( 3 ) 
          AND 1 = 1 
          AND 1 = 1 
          AND 1 = 1 
   GROUP  BY 1 
   HAVING 1 = 1 
   ORDER  BY chitentrygroup.chitentrygroupid DESC ) AS t 
      LIMIT  0, 10 

現在,當我刪除 SQL_CALC_FOUND_ROWS 時, Group By 並擁有查詢的一部分。查詢速度很快。我所說的上述任何內容的存在都會使查詢卡在這個大表上。

我應該如何使用 Group By、Having 和 SQL_CALC_FOUND_ROWS 子句優化此查詢?

去掉外層:

SELECT  SQL_CALC_FOUND_ROWS  ...
   FROM (SELECT ...
           ORDER  BY chitentrygroup.chitentrygroupid DESC
        ) AS t 
  LIMIT  0, 10

–>

SELECT  SQL_CALC_FOUND_ROWS  ...
  ORDER  BY chitentrygroup.chitentrygroupid DESC
  LIMIT  0, 10

這也將修復您可能沒有註意到的錯誤。派生表返回一組無序的行。也就是說,允許優化器忽略您擁有的ORDER BY公式中的 。這給你的不是前 10 行,而是一些任意的 10 行。

FOUND_ROWS過去了。您是否注意到搜尋引擎首先移動到“大約 1,000,000 次點擊”,然後擺脫了計數?你真的需要計數嗎?

你有什麼索引chitentrygroup?特別是,這可能是有益的:

INDEX(industryid, status)

你在使用 InnoDB 嗎?的價值是多少innodb_buffer_pool_size。對於 2GB 的小型機器(或 VM),它應該不超過 400M。

您正在執行什麼版本的 MySQL?舊版本預設為 8M 或 128M。這些太小。

什麼是映射?有一個employeechitentrygroupid?那是“1:許多”。account和怎麼樣chitentry?如果這些都是 1:many,你就不需要GROUP BY——這才是真正的反派。

也就是說,如果您可以SELECT使用 chitentrygroupids,通過ORDER BY並且LIMIT 不需要ORDER BY您可以避免使用JOIN + GROUP BY.

可能它的語法是錯誤的:

和 1 = 1 和 1 = 1 和 1 = 1 按 1 分組

交換

group by 1 #第一列的名稱

嘗試交易

按 table.field 排序

例子

此方法耗時稍長 SQL_CALC_FOUND_ROWS;您是否嘗試過使用 count()

我發現使用某些方法來獲得響應時間很酷

http://phpdevblog.niknovo.com/2009/06/mysql-pagination-sql-calc-found-rows-vs-count-query.html

引用自:https://dba.stackexchange.com/questions/198816