0

我有一张接近 2000 万条记录并且还在不断增长的表。该表设置为 innodb。两个主要字段上有一个主索引:

`entries_to_fields`
entry_id    int(11) NO  PRI NULL     
field_id    int(11) NO  PRI NULL     
value   text    NO      NULL     

尽管记录数量众多,但对该表的大多数查询都非常快,但以下情况除外:

DELETE FROM `entries_to_fields` WHERE `entry_id` IN (SELECT `id` FROM `entries` WHERE `form_id` = 196)

这将删除特定表单的所有条目数据。

目前这需要超过 45 秒,即使条目表没有返回结果。

我的问题是entries_to_fields我可以对结构进行简单的更改,还是可以进一步优化我的查询。

4

3 回答 3

3

阅读您的答案后,我编写了此查询,该查询也可能对您有所帮助(将来)。

DELETE entries_to_fields
FROM entries_to_fields
JOIN entries
ON entries_to_fields.entry_id = entries.id
WHERE entries.form_id = 196

... entry.form_id 字段应该被索引。

于 2011-08-02T06:23:30.443 回答
1

经过一些试验和错误+谷歌搜索后,我发现IN在大表上使用索引字段是一种非常糟糕的做法。

我已将子查询分解为单独的查询,然后创建了一个动态查询,如下所示:

DELETE FROM `entries_to_fields` WHERE `entry_id` = 232 OR `entry_id` = 342 ...

尽管生成了一个潜在的大型查询,但它现在在 ~1 秒内执行。即使在删除 1000 个条目时。

于 2011-08-02T06:15:46.820 回答
1

我会查看查询计划,我的猜测是子查询返回 NULL 并进行删除全扫描。

看 :

http://dev.mysql.com/doc/refman/5.0/en/in-subquery-optimization.html

于 2011-08-02T06:27:24.143 回答