[英]Mysql Count query optimization
I have the below query to optimize. 我有以下查询要优化。
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
There are indexes on deleted, ids on all the tables. 在所有表上都有已删除索引,id。
Now when i have suppose 20 Lac (2 million) of records then the query takes lots of time to give me the result. 现在,当我假设有20个Lac(200万个)记录时,该查询将花费大量时间才能得出结果。 Its between 10 to 20 seconds.
它在10到20秒之间。
How can i optimize it more. 我如何进一步优化它。 Also is there any other technique to get count.
还有没有其他技术可以计数。
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
New explain for composite key 复合键的新说明
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
As per comments, if you want to keep the query in question - you have to allocate more resources to your MySQL instance. 根据注释,如果您想保持查询的状态-您必须为您的MySQL实例分配更多资源。 I am assuming you use InnoDB for storage engine, otherwise this advice is useless:
我假设您将InnoDB用于存储引擎,否则此建议无用:
Increase the value of innodb_buffer_pool
variable. 增加
innodb_buffer_pool
变量的值。 As much as you can. 尽你所能地。 You want to allocate as much RAM as possible.
您想要分配尽可能多的RAM。
Also, get rid of index on deleted
column, it's useless. 此外,摆脱
deleted
列上的索引,这是没有用的。 Its cardinality is too low for it to be an index. 它的基数太低,无法作为索引。
The other "technique" that you can (should) use is taking care of this count manually. 您可以(应该)使用的另一种“技术”是手动处理此计数。
Create the table that holds the count number you are interested in. Every time you update / insert / delete the entity or area record - update the count value manually (increase, decrease). 创建包含您感兴趣的计数编号的表。每次更新/插入/删除实体或区域记录-手动更新计数值(增加,减少)。
That way all you have to do is look up a single record of a single table. 这样,您要做的就是查找单个表的单个记录。 Setting up triggers that will sort this out automatically should be trivial.
设置将自动解决此问题的触发器应该很简单。 That way you'll take care of the count at runtime instead waste I/O and CPU to constantly traverse the data set.
这样,您将在运行时处理计数,而不是浪费I / O和CPU来不断遍历数据集。
You could try: 您可以尝试:
SELECT count(*) AS count
FROM area
JOIN entity
ON entity.id = area.id
AND entity.deleted = 0
JOIN areacust
ON areacust.id = area.id
I like to include conditions in JOINs where possible and keep the table I'm JOINing on the left of the equals in these conditions. 我希望在可能的情况下在JOIN中包含条件,并在这些条件下将要加入的表保持在等号的左侧。
Also the WHERE area.id > 0
was strange.. most foreign_keys start at 1 due to auto_increment ids in other tables so this will include all rows. 同样
WHERE area.id > 0
也很奇怪..由于其他表中的auto_increment id,大多数foreign_keys从1开始,因此它将包括所有行。 I have deleted this condition. 我已删除此条件。
From the look of your explain, you don't really want the top row to be using entity_deleted_idx
. 从您的解释来看,您实际上并不希望最上面的行使用
entity_deleted_idx
。 You may get more joy with a composite index on (id, deleted)
for entity
在
entity
(id, deleted)
上使用复合索引可能会带来更多乐趣
These are the indexes i'd have for this query: 这些是我对此查询的索引:
area
- (id) This is probably the PRIMARY already area
-(id)这可能已经是PRIMARY areacust
- (id) This is probably the PRIMARY already areacust
(id)这可能已经是PRIMARY entity
- (id, deleted) This should be added and used. entity
-(标识,已删除)应添加和使用。 UPDATE UPDATE
Remove all unsused indexes from the table entity
except for the PRIMARY and the composite index. 从表
entity
删除所有未使用的索引,但PRIMARY和复合索引除外。
If that doesn't work run: 如果那不起作用,请运行:
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.