我有一个相当简单的表,大约有一百万行。
id | my_col | other1 | other 2 | ...
此表中有大约15k个不同的my_col值,而my_col上有一个索引。我有一组7k my_col值,我需要从这个表中删除。
在SQL中做什么更有效(我目前正在使用MySQL,但将来可能会移植到MS SQL。)
是否a)在我的java应用程序代码中,遍历所有my_col值并在每个值上调用sql delete。
for (String my_colValue : listMyCol) {
[delete from my_table where my_col = my_colValue]
}
或b)使用“where in”子句构建包含所有这些值的单个SQL [large]语句?
delete from my_table where my_col in ('aaa', 'aab', 'aac', ...)
我猜它是b),但我不确定在“where in”子句中指定约7k值是否效率低。
为了它的价值,我的应用服务器和数据库服务器都托管在亚马逊,但在不同的层上。
答案 0 :(得分:2)
c)重新创建你的桌子。
你要删除一半的行,所以想一想。 虽然a)和b)可能会永远占用,但重新制作你的桌子会很诡异但是很快。
您需要在临时表中加载7k值,然后很容易:
CREATE TABLE newMyTable
AS
SELECT myTable.*
FROM myTable
INNER JOIN myValues
ON myTable.my_col = myValues.my_col
或者,如果你不能创建表,也许这会足够快:
DELETE FROM myTable t
WHERE EXISTS
(
SELECT *
FROM myValues v
WHERE t.my_col = v.my_col
)
但是你需要记住的唯一事情是:你必须用你的7k值创建一个表。
答案 1 :(得分:2)
使用WHERE IN
的实际限制是你可以在多大程度上进行SQL查询。这是由MySQL的max_packet_size
配置变量定义的。其他任何事情只是性能权衡。为了找出最快的方法,基准测试仍然效果最好。
答案 2 :(得分:1)
我会选择第一个选项,但我会将所有内容都放在交易中。这样,提交将在最后,而不是在每个DELETE语句之后。
搜索许多记录时,索引效率低下。