How ClickHouse Evaluates IN with Hash Sets
x IN (1, 2, 3) looks like a comparison. x IN (SELECT user_id FROM logins WHERE …) looks like a join. Under the hood both become the same thing: a hash set, built once, probed once …
x IN (1, 2, 3) looks like a comparison. x IN (SELECT user_id FROM logins WHERE …) looks like a join. Under the hood both become the same thing: a hash set, built once, probed once …
Every columnar database pays the same tax: a SELECT is not a loop over rows, it is a graph of actions, and every action dispatches through a virtual call per block. The block is …
Every GROUP BY in ClickHouse is a hash table. The table has to hold millions of keys, be probed once per input row, and be resized while it is being filled — all while the query is …
Every MergeTree table is a pile of immutable parts. Every part is a pile of immutable columns. Background merges take a contiguous range of parts and rewrite them as one bigger …
Strings are the most common GROUP BY key in practice. They are also the worst case for a hash table: a std::string in a cell means one heap allocation per distinct key, and a …