 This bug is reproduced on any version ( 22.1.3.7 , 22.3.11.12 , 22.9.3)

**How to reproduce** 
*(cant reproduce well on fiddle, but easy locally or on production)*

**NOT OK (with preallocate)**
```
CREATE TABLE default.oom_table (key String) ENGINE = MergeTree() ORDER BY tuple();

INSERT INTO default.oom_table SELECT hex(sipHash128(toString(number % 100))) FROM numbers(1000000000);

CREATE VIEW default.oom_view AS SELECT xxHash32(key) hash, key FROM default.oom_table GROUP BY key;

CREATE DICTIONARY default.oom_dict (hash UInt32, key String) PRIMARY KEY hash SOURCE(CLICKHOUSE(host 'localhost' user 'default' port 9000 db 'default' table 'oom_view')) LAYOUT (HASHED(PREALLOCATE 1)) LIFETIME (600);

SELECT * FROM dictionary('default.oom_dict');
```

**Error**
```
Code: 241. DB::Exception: Received from clickhouse-server:9000. DB::Exception: Memory limit (total) exceeded: would use 48.48 GiB (attempt to allocate chunk of 51540792506 bytes), maximum: 13.50 GiB. OvercommitTracker decision: Query was selected to stop by OvercommitTracker.. (MEMORY_LIMIT_EXCEEDED)

```

**OK (without preallocate)**
```
CREATE TABLE default.oom_table (key String) ENGINE = MergeTree() ORDER BY tuple();

INSERT INTO default.oom_table SELECT hex(sipHash128(toString(number % 100))) FROM numbers(1000000000);

CREATE VIEW default.oom_view AS SELECT xxHash32(key) hash, key FROM default.oom_table GROUP BY key;

CREATE DICTIONARY default.oom_dict (hash UInt32, key String) PRIMARY KEY hash SOURCE(CLICKHOUSE(host 'localhost' user 'default' port 9000 db 'default' table 'oom_view')) LAYOUT (HASHED()) LIFETIME (600);

SELECT * FROM dictionary('default.oom_dict');
```


{
    return createStreamForQuery(query_builder.composeLoadIdsQuery(ids));
}
QueryPipeline ClickHouseDictionarySource::loadKeys(const Columns & key_columns, const std::vector<size_t> & requested_rows)
{
    String query = query_builder.composeLoadKeysQuery(key_columns, requested_rows, ExternalQueryBuilder::IN_WITH_TUPLES);
    return createStreamForQuery(query);
}
bool ClickHouseDictionarySource::isModified() const
{
    if (!configuration.invalidate_query.empty())
    {
        auto response = doInvalidateQuery(configuration.invalidate_query);
        LOG_TRACE(log, "Invalidate query has returned: {}, previous value: {}", response, invalidate_query_response);
        if (invalidate_query_response == response)
            return false;
        invalidate_query_response = response;
    }
    return true;
}
bool ClickHouseDictionarySource::hasUpdateField() const
{
    return !configuration.update_field.empty();
}
std::string ClickHouseDictionarySource::toString() const
{
    const std::string & where = configuration.where;
    return "ClickHouse: " + configuration.db + '.' + configuration.table + (where.empty() ? "" : ", where: " + where);
}
QueryPipeline ClickHouseDictionarySource::createStreamForQuery(const String & query, std::atomic<size_t> * result_size_hint)