使用select count(*)对更新进行慢查询

时间:2011-09-07 08:08:57

标签: mysql performance select count indexing

我必须计算table2中的数字在范围table2.a和table2.b中的数字之间出现的次数

即。我们想知道我们有多少次:a<开始< B'/ P>

我运行了以下查询:

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

table2 as

  • a,b和发生的3个索引
  • 1567行(因此我们将在table2上选择COUNT(*)1567次..)
  • ID列为PK

table1 as

  • 启动时索引
  • 42,000,000行
  • 列开始是“按列开始排序”
  • ID列为PK

==>花了2.5小时做了2/3。我需要加快速度......任何建议? :)

4 个答案:

答案 0 :(得分:1)

您可以尝试将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);

这称为“覆盖索引”:http://www.simple-talk.com/sql/learn-sql-server/using-covering-indexes-to-improve-query-performance/

- >表1中的整个查询可以通过索引中的数据提供 - >没有额外的页面查找实际记录。

答案 1 :(得分:1)

使用存储过程。将COUNT的结果保存在局部变量中,然后使用它来运行UPDATE查询。

答案 2 :(得分:0)

我会这样做

// 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;

答案 3 :(得分:-1)

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

UPDATE table2
 SET occurrence =  
       (SELECT COUNT(1) FROM table1 WHERE start BETWEEN table2.a AND table2.b);