我有一张接近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
结构进行简单的更改,还是可以进一步优化我的查询。
答案 0 :(得分:3)
在我读完你的答案之后,我写了这个查询,可以帮助你(将来)。
DELETE entries_to_fields
FROM entries_to_fields
JOIN entries
ON entries_to_fields.entry_id = entries.id
WHERE entries.form_id = 196
... entries.form_id字段应编入索引。
答案 1 :(得分:1)
经过一段时间的试验&错误+谷歌搜索,我发现在大型表的索引字段上使用IN
是一个非常糟糕的做法。
我已将子查询分解为单独的查询,然后按如下方式创建动态查询:
DELETE FROM `entries_to_fields` WHERE `entry_id` = 232 OR `entry_id` = 342 ...
尽管产生了潜在的大型查询,但现在在约1秒内执行。即使删除了1000个条目。
答案 2 :(得分:1)
我会查看查询计划,我的猜测是子查询返回NULL并进行删除全扫描。
见:
http://dev.mysql.com/doc/refman/5.0/en/in-subquery-optimization.html