-1

我有一个 MySQL MYISAM 表(比如 tbl),它由 2 个无符号整数字段组成,比如 f1 和 f2。f2 上有一个索引,表非常大(大约 320,000,000+ 行)。我定期更新此表(每周大约有 100,000 条新行),并且为了能够在不执行 ORDER BY 的情况下搜索此表(这在实时查询中会非常耗时),我对表进行物理排序根据我要检索其行的方式。

所以,我执行 ALTER TABLE tbl ORDER BY f1 DESC。(我知道我在服务器上有足够的物理空间来存储表的副本。)我读到,在此操作期间,会创建一个临时表,并且 SELECT 语句不会影响当前行。

但是,我的经验并非如此,并且与 ALTER 表同时发生的表上的 SELECT 语句被阻塞并且不会终止。ALTER TABLE tbl 完成后(在生产服务器上大约 40 分钟),tbl 上的 SELECT 语句再次开始正常执行。

为什么“ALTER table tbl ORDER BY f1 DESC”似乎阻止其他客户端查询 tbl 有什么原因吗?

4

1 回答 1

0

更改表将始终获取表上的锁,从而阻止 SELECT 运行。

我会管理我什至不知道您可以使用 ALTER TABLE 来做到这一点。

你想从桌子上得到什么?例如,给定范围内的所有记录?3.2 亿行不是一个微不足道的数字。我会给你我的直觉反应:

  1. 切换到 InnoDB(允许 #2,也提供事务,但没有 #2 可能会影响性能)
  2. 对表进行分区(使其像许多稍小的表一样)
  3. 考虑重新设计,例如有一个“工作集”表和一个“历史”表,基本上是手动分区。如果您通常查找最近插入的数据,这(连同分区)将有很大帮助。如果您的查找是均匀分布的,这可能不会有什么不同。
  4. 考虑添加一个新列,您可以结合使用来缩小选择范围(因此不是搜索日期,而是搜索日期和客户 ID)

由于我不知道您要存储什么,因此其中一些(例如#4)可能不适用。

您还可以尝试其他一些事情。OPTIMIZE TABLE 可能会对您有所帮助,但需要的时间更少,但我对此表示怀疑。我认为在内部它被实现为转储/重新加载,至少在 InnoDB 方面。

于 2010-12-18T00:12:54.230 回答