I made a small benchmark.
Source code on pastebin
Test table: 10M rows with (id INT PRIMARY KEY, s TEXT).
Results:
0.055ms 1 rows Correlated SELECT * FROM test_array WHERE id =ANY(A
0.042ms 1 rows Correlated SELECT * FROM test_array WHERE id IN (1)
0.070ms 1 rows Correlated SELECT * FROM unnest(ARRAY[1]) id JOIN t
0.045ms 1 rows Random SELECT * FROM test_array WHERE id =ANY(A
0.042ms 1 rows Random SELECT * FROM test_array WHERE id IN (31
0.070ms 1 rows Random SELECT * FROM unnest(ARRAY[3146607]) id
0.058ms 10 rows Correlated SELECT * FROM test_array WHERE id =ANY(A
0.059ms 10 rows Correlated SELECT * FROM test_array WHERE id IN (1,
0.085ms 10 rows Correlated SELECT * FROM unnest(ARRAY[1,2,3,4,5,6,7
0.065ms 10 rows Random SELECT * FROM test_array WHERE id =ANY(A
0.062ms 10 rows Random SELECT * FROM test_array WHERE id IN (66
0.088ms 10 rows Random SELECT * FROM unnest(ARRAY[6629054,48357
0.184ms 100 rows Correlated SELECT * FROM test_array WHERE id =ANY(A
0.183ms 100 rows Correlated SELECT * FROM test_array WHERE id IN (1,
0.222ms 100 rows Correlated SELECT * FROM unnest(ARRAY[1,2,3,4,5,6,7
0.247ms 100 rows Random SELECT * FROM test_array WHERE id =ANY(A
0.237ms 100 rows Random SELECT * FROM test_array WHERE id IN (15
0.258ms 100 rows Random SELECT * FROM unnest(ARRAY[153046,957664
1.442ms 1000 rows Correlated SELECT * FROM test_array WHERE id =ANY(A
1.458ms 1000 rows Correlated SELECT * FROM test_array WHERE id IN (1,
1.558ms 1000 rows Correlated SELECT * FROM unnest(ARRAY[1,2,3,4,5,6,7
2.076ms 1000 rows Random SELECT * FROM test_array WHERE id =ANY(A
2.019ms 1000 rows Random SELECT * FROM test_array WHERE id IN (90
2.070ms 1000 rows Random SELECT * FROM unnest(ARRAY[9047600,58146
15.233ms 10000 rows Correlated SELECT * FROM test_array WHERE id =ANY(A
14.536ms 10000 rows Correlated SELECT * FROM test_array WHERE id IN (1,
15.389ms 10000 rows Correlated SELECT * FROM unnest(ARRAY[1,2,3,4,5,6,7
62.936ms 9995 rows Random SELECT * FROM test_array WHERE id =ANY(A
47.661ms 9995 rows Random SELECT * FROM test_array WHERE id IN (31
36.861ms 10000 rows Random SELECT * FROM unnest(ARRAY[3109119,87658
421.528ms 100000 rows Correlated SELECT * FROM test_array WHERE id =ANY(A
413.692ms 100000 rows Correlated SELECT * FROM test_array WHERE id IN (1,
95.054ms 100000 rows Correlated SELECT * FROM unnest(ARRAY[1,2,3,4,5,6,7
413.768ms 99482 rows Random SELECT * FROM test_array WHERE id =ANY(A
411.587ms 99482 rows Random SELECT * FROM test_array WHERE id IN (33
508.202ms 100000 rows Random SELECT * FROM unnest(ARRAY[3364043,10450
Interpretation:
There is no difference between "WHERE id IN (...)" and "WHERE id =ANY(...)".
How does this query type scale? I assume the array is not indexed, so presumably each array value hits the index, giving scaling of O(n.N), for n array values, and N table rows?
Assuming the column being searched is indexed, it does one index lookup for each value in the array, at a cost of O(log N). With n array values, that's a total cost of O(n log N). As expected, there is a small fixed cost to run a query, then it scales pretty much linearly with the number of rows returned.
I have included two cases: "Correlated" where ids for retrieved rows are consecutive, and "Random" where they are randomized over the whole table. As expected, the various caches (from CPU L1 to OS disk cache) do their job, so it's faster to retrieve data with higher locality of reference.
Anyway, at 2 microseconds per row, database CPU load is pretty low.
However, this runs on a SSD and the table is cached in RAM. In a more "real world" situation, where parts of the table would not be cached, if you retrieve random rows you can expect one random access per row. This may be quite slow, depending on your hardware, but... that has nothing to do with postgres itself. That depends entirely on your IO system and how well your data is cached. If you use spinning disks and data isn't cached, and you don't particularly care about this query being as fast as possible then maybe slicing it into smaller lists of rows would reduce disk trashing.
I also included a third test case:
SELECT * FROM unnest(ARRAY[%s]) id JOIN test_array USING (id)
When the length of the array is very large, the other queries simply do a parallel seq scan. This is very fast, because the "Filter where id=ANY(...)" isn't dumb, it uses some kind of fast search like hashing or bisect, it doesn't compare every row with every value of the array.
This last query is interesting because it's a join, so postgres optimizes it as a join, which may be faster... or slower... in some cases.