【问题标题】:whole table updates整表更新
【发布时间】:2011-07-18 15:59:35
【问题描述】:

目前我们使用 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)?

对此有什么想法吗?

【问题讨论】:

  • 为什么要“移动”对象?这意味着什么?你能举一个真实的例子,而不是你的注释版本,因为某种原因删除了所有多汁的部分吗?
  • 我同意...移动似乎是错误的,而是在某处更新状态。并展示为获得实际帮助而付出的实际努力。
  • 我有 iphone 游戏 Floonr,人们可以在其中发射虚拟气球并在真实地图上跟踪它。我根据纬度,经度模拟每次更新时的风变化

标签: mysql optimization query-optimization


【解决方案1】:

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

  • 创建临时表
  • 用大 INSERT 填充(主键,新值)
  • UPDATE table 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)

【讨论】:

  • 看起来很有趣,会尝试一下
  • 嗯,这种更新似乎不适用于空间索引。如果我包含索引列,我总是会收到错误:'#126 - 表'tablename.MYI'的密钥文件不正确;尝试修复它'并且修复无济于事。如果我删除空间索引,一切似乎都正常
  • 测试表中有空间索引吗?
  • 嗯,#126 的错误信息特别有用诶!当我尝试在可为空的列上创建空间索引时,我得到“错误 1252 (42000):空间索引的所有部分都必须不是 NULL”。所以也许你的 mysql 版本是旧的/错误的?
  • 我有 5.1.52(亚马逊云上的最新默认值)。是的-错误不是很有帮助:)我不是在尝试创建时得到它,而是在我尝试将记录推回时得到它(最后一步)
猜你喜欢
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多