Mysql 使用select count(*)进行更新时的慢速查询
我必须计算表2中的数字在表2.a和表2.b范围内出现的次数 i、 我们想知道我们有多少次这样:aMysql 使用select count(*)进行更新时的慢速查询,mysql,performance,select,count,indexing,Mysql,Performance,Select,Count,Indexing,我必须计算表2中的数字在表2.a和表2.b范围内出现的次数 i、 我们想知道我们有多少次这样:a表1上的整个查询可以通过索引中的数据->无需对实际记录进行额外的页面查找。使用存储过程。将COUNT的结果保留在局部变量中,然后使用它来运行更新查询。您是否尝试过对查询执行EXPLAIN EXTENDED操作?是的,但它不能告诉我太多。我对此没有衡量标准,您可以发布SELECT语句的解释计划。然后我们可以进一步讨论它是否应该是table1.start而不是table1.id?这种方法是有希望的!你切换
UPDATE table2
SET occurrence =
(SELECT COUNT(*) FROM table1 WHERE start BETWEEN table2.a AND table2.b);
table2
ID a b occurrence
1 1 10
2 1 20
3 1 25
4 2 30
table1
ID start col1 col2 col3
1 1
2 7
3 10
4 21
5 25
6 27
7 30
表2 as
- 关于a、b和事件的3个索引
- 1567行(因此我们将在表2中选择计数(*)1567次)
- ID列作为PK
- 1开始时的索引
- 42000000行
- 列开始为“按列开始排序”
- ID列作为PK
UPDATE table2
SET occurrence =
(SELECT COUNT(1) FROM table1 WHERE start BETWEEN table2.a AND table2.b);
我会这样做
// use one expensive join
create table tmp
select table2.id, count(*) as occurrence
from table1
inner join table1
on table1.start between table2.a and table2.b
group by table1.id;
update table2, tmp
set table2.occurrence=tmp.occurrence
where table2.id=tmp.id;
您可以尝试将id列添加到表1的索引中:
CREATE INDEX start_index ON table1 (start,id);
并将查询重写为
UPDATE table2
SET occurrence =
(SELECT COUNT(id) FROM table1 WHERE start BETWEEN table2.a AND table2.b);
这称为“覆盖指数”:
->表1上的整个查询可以通过索引中的数据->无需对实际记录进行额外的页面查找。使用存储过程。将COUNT的结果保留在局部变量中,然后使用它来运行更新查询。您是否尝试过对查询执行
EXPLAIN EXTENDED
操作?是的,但它不能告诉我太多。我对此没有衡量标准,您可以发布SELECT语句的解释计划。然后我们可以进一步讨论它是否应该是table1.start而不是table1.id?这种方法是有希望的!你切换了表1和表2?谢谢,我试过了,花了整整一个晚上才更新了一张表。。我不确定这是不是最好的方式去做同样的表现和解释计划作为计数(*)?在这种情况下,我猜乐观主义者足够聪明,在这两种情况下都只需读取索引。