0

我的 MySQL 数据库的简化版本如下所示:

Table books (ENGINE=MyISAM)
id <- KEY
publisher <- LONGTEXT
publisher_id <- INT <- This is a new field that is currently null for all records

Table publishers (ENGINE=MyISAM)
id <- KEY
name <- LONGTEXT

目前,books.publisher 持有不断重复的值,但 publishers.name 持有唯一的值。我想摆脱 books.publisher 而是填充 books.publisher_id 字段。

描述我想要做的简单的 SQL 代码如下:

UPDATE books 
JOIN publishers ON books.publisher = publishers.name 
SET books.publisher_id = publishers.id;

问题是我有大量记录,即使它有效,它也需要永远。

有没有比提前使用这样的东西更快的解决方案?:

CREATE INDEX publisher ON books (publisher(20));
4

3 回答 3

2

您的问题标题是“..优化...查询而不使用索引?”

你有什么反对使用索引的?

如果查询运行缓慢,您应该始终检查执行计划。我猜它必须扫描publishers表格的每一行才能找到匹配项。有一个索引publishers.name来加快id.

您可以稍后删除索引,但保留它不会有任何害处,因为您说该过程必须运行一段时间,直到进行其他更改。我想publishers桌子不会经常更新,所以桌子上的性能INSERT应该UPDATE不是问题。

于 2013-11-01T13:12:10.907 回答
1

这里有一些问题可以通过优化得到帮助。

首先,几千行不算“大”……那是“中”。

其次,在 MySQL 中说“我想在没有索引的情况下执行此操作”就像在说“我想开车去纽约市,但是我的轮胎没气了,我不想给它们打气。什么是最好的路线?纽约,如果我在我的轮辋上开车?”

第三,您正在LONGTEXT为您的发布者使用一个项目。有什么理由不使用完全可索引的数据类型VARCHAR(200)吗?如果你这样做,你的 WHERE 语句将运行得更快,索引或无。大型图书馆目录系统限制了发布者字段的长度,因此您的系统也可以。

第四,从您的一条评论来看,这看起来像是例行数据维护更新,而不是一次性转换。因此,您需要弄清楚如何避免一遍又一遍地重复整个交易。我在这里猜测,但看起来您books表中新插入的行的 publisher_id 为零,并且您的查询将该列更新为有效值。

所以这里是做什么。首先,在tables.publisher_id 上放置一个索引。

其次,运行维护查询的这个变体:

UPDATE books 
  JOIN publishers ON books.publisher = publishers.name 
   SET books.publisher_id = publishers.id
 WHERE books.publisher_id = 0
 LIMIT 100;

这会将您的更新限制为尚未更新的行。它还将一次更新 100 行。在您的每周数据维护工作中,重新发出此查询,直到 MySQL 宣布您的查询影响了零行(查看 mysqli::rows_affected 或 php-to-mysql 接口中的等效项)。这是监控数据库更新进度和防止更新操作失控的好方法。

于 2013-11-01T13:23:35.220 回答
-1

您的更新查询语法无效,但您可以稍后修复。让它运行得更快的方法是添加一个 where 子句,以便您只更新必要的记录。

于 2013-11-01T13:00:27.967 回答