整表更新

时间:2011-07-17 03:38:36

标签: mysql optimization query-optimization

目前我们使用MySQL。

我们有空间索引的表(所以没有InnoDB),并且每隔x秒进行一次整表更新(将对象从一个地方移动到另一个地方)。

目前我们在做:

UPDATE LOW_PRIORITY IGNORE `table`
SET `column1` = CASE `column2`
              WHEN 1 THEN ...
              WHEN 2 THEN ...
              WHEN 3 THEN ...
              ...
              ELSE `column1`
              END;

但随着行数的增加,它会变得非常痛苦。是否有更好的方法来进行整个表格更新?也许我们应该切换到其他数据库(PostGIS,NoSQL)?

对此有何看法?

1 个答案:

答案 0 :(得分:0)

一次更新多行的最佳方法是:

  • 创建TEMP表
  • 使用大型INSERT
  • 填充(主键,新值)
  • UPDATE表JOIN temptable USING(主键)SET table.oldvalue = temptable.newvalue

更新:

create table test ( id integer primary key, p point not null );
insert into test (id,p) select id, POINT( id%100, floor(id/100) ) from serie limit 10000;
alter table test add spatial index spi (p);
select id, AsText(p) from test;

+----+-------------+
| id | AsText(p)   |
+----+-------------+
|  1 | POINT(1 0)  |
|  2 | POINT(2 0)  |
|  3 | POINT(3 0)  |
...

|  98 | POINT(98 0) |
|  99 | POINT(99 0) |
| 100 | POINT(0 1)  |
| 101 | POINT(1 1)  |
...

|  9999 | POINT(99 99) |
| 10000 | POINT(0 100) |
+-------+--------------+


EXPLAIN SELECT id,AsText(p) from test where Contains( GeomFromText('POLYGON((0 0,0 10,10 10,10 0,0 0))'), p );
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | test  | range | spi           | spi  | 34      | NULL |  112 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+

create temporary table test2 ( id integer primary key, p point not null );
insert into test2 (id,p) select id, POINT( 1+(id%100), 1+floor(id/100) ) from serie limit 10000;
update test, test2 set test.p=test2.p where test.id=test2.id;

EXPLAIN SELECT id,AsText(p) from test where Contains( GeomFromText('POLYGON((0 0,0 10,10 10,10 0,0 0))'), p );
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | test  | range | spi           | spi  | 34      | NULL |  102 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+

这里没问题(MySQL 5.1.41)