簡體   English   中英

MySQL計數查詢優化

[英]Mysql Count query optimization

我有以下查詢要優化。

SELECT count(*) AS count FROM area 
INNER JOIN entity ON area.id = entity.id
INNER JOIN areacust ON area.id = areacust.id 
WHERE entity.deleted=0 
AND area.id > 0

在所有表上都有已刪除索引,id。

現在,當我假設有20個Lac(200萬個)記錄時,該查詢將花費大量時間才能得出結果。 它在10到20秒之間。

我如何進一步優化它。 還有沒有其他技術可以計數。

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  vtiger_crmentity    ref PRIMARY,entity_deleted_idx  entity_deleted_idx  4      const    729726  Using where; Using index
1   SIMPLE  area    eq_ref  PRIMARY PRIMARY 4   area.id 1   Using index
1   SIMPLE  areacust    eq_ref  PRIMARY PRIMARY 4   area.id 1   Using where; Using index

復合鍵的新說明

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  entity  ref PRIMARY,entity_deleted_idx,comp_index   deleted_idx 4   const   928304  Using index
1   SIMPLE  area    eq_ref  PRIMARY PRIMARY 4   entity.id   1   Using index
1   SIMPLE  areacust    eq_ref  PRIMARY PRIMARY 4   entity.idid 1   Using index

根據注釋,如果您想保持查詢的狀態-您必須為您的MySQL實例分配更多資源。 我假設您將InnoDB用於存儲引擎,否則此建議無用:

增加innodb_buffer_pool變量的值。 盡你所能地。 您想要分配盡可能多的RAM。

此外,擺脫deleted列上的索引,這是沒有用的。 它的基數太低,無法作為索引。

您可以(應該)使用的另一種“技術”是手動處理此計數。

創建包含您感興趣的計數編號的表。每次更新/插入/刪除實體或區域記錄-手動更新計數值(增加,減少)。

這樣,您要做的就是查找單個表的單個記錄。 設置將自動解決此問題的觸發器應該很簡單。 這樣,您將在運行時處理計數,而不是浪費I / O和CPU來不斷遍歷數據集。

您可以嘗試:

SELECT count(*) AS count 
  FROM area 
  JOIN entity
    ON entity.id = area.id
   AND entity.deleted = 0 
  JOIN areacust 
    ON areacust.id = area.id 

我希望在可能的情況下在JOIN中包含條件,並在這些條件下將要加入的表保持在等號的左側。

同樣WHERE area.id > 0也很奇怪..由於其他表中的auto_increment id,大多數foreign_keys從1開始,因此它將包括所有行。 我已刪除此條件。

從您的解釋來看,您實際上並不希望最上面的行使用entity_deleted_idx entity (id, deleted)上使用復合索引可能會帶來更多樂趣

這些是我對此查詢的索引:

  • area -(id)這可能已經是PRIMARY
  • areacust (id)這可能已經是PRIMARY
  • entity -(標識,已刪除)應添加和使用。

UPDATE

從表entity刪除所有未使用的索引,但PRIMARY和復合索引除外。

如果那不起作用,請運行:

SELECT count(*) AS count 
  FROM area 
  JOIN entity USE INDEX (**composite_index_name**)
    ON entity.id = area.id
   AND entity.deleted = 0 
  JOIN areacust 
    ON areacust.id = area.id 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM