Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用select count(*)进行更新时的慢速查询_Mysql_Performance_Select_Count_Indexing - Fatal编程技术网

Mysql 使用select count(*)进行更新时的慢速查询

Mysql 使用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?这种方法是有希望的!你切换

我必须计算表2中的数字在表2.a和表2.b范围内出现的次数

i、 我们想知道我们有多少次这样:a 我运行了以下查询:

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 as

  • 1开始时的索引
  • 42000000行
  • 列开始为“按列开始排序”
  • ID列作为PK
==>花了2.5个小时完成了其中的2/3。我需要加快速度。。。有什么建议吗?:)

我认为count(*)使数据库读取数据行,而在您的情况下,它只需要读取索引。尝试:

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?谢谢,我试过了,花了整整一个晚上才更新了一张表。。我不确定这是不是最好的方式去做同样的表现和解释计划作为计数(*)?在这种情况下,我猜乐观主义者足够聪明,在这两种情况下都只需读取索引。