[英]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.