 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');
```


element_count += new_element_count;
        return;
    }
    for (size_t attribute_index = 0; attribute_index < attributes_size; ++attribute_index)
    {
        const IColumn & attribute_column = *block.safeGetByPosition(skip_keys_size_offset + attribute_index).column;
        auto & attribute = attributes[attribute_index];
        bool attribute_is_nullable = attribute.is_nullable_set.has_value();
        getAttributeContainer(attribute_index, [&](auto & containers)
        {
            using ContainerType = std::decay_t<decltype(containers.front())>;
            using AttributeValueType = typename ContainerType::mapped_type;
            for (size_t key_index = 0; key_index < keys_size; ++key_index)
            {
                auto key = keys_extractor.extractCurrentKey();
                auto & container = containers[shard];
                auto it = container.find(key);
                bool key_is_nullable_and_already_exists = attribute_is_nullable && attribute.is_nullable_set->find(key) != nullptr;
                if (key_is_nullable_and_already_exists || it != container.end())
                {
                    keys_extractor.rollbackCurrentKey();
                    continue;
                }
                if constexpr (std::is_same_v<KeyType, StringRef>)
                    key = copyStringInArena(*string_arenas[shard], key);
                attribute_column.get(key_index, column_value_to_insert);
                if (attribute.is_nullable_set && column_value_to_insert.isNull())
                {
                    attribute.is_nullable_set->insert(key);
                    keys_extractor.rollbackCurrentKey();