It would be great if `optimize_on_insert` was smart enough to discard empty blocks
```
create table empty (num Int8) engine=Memory;
CREATE MATERIALIZED VIEW empty_mv
(
    `num` Int8
)
ENGINE = SummingMergeTree
ORDER BY tuple() AS
SELECT num
FROM empty;

-- First insert

set optimize_on_insert=1;
insert into empty values (0);

-- 20 minutes break

set optimize_on_insert=0;
insert into empty values (0);

-- Created parts

SELECT
    event_type,
    event_time,
    table,
    part_name,
    rows
FROM system.part_log
PREWHERE (event_date = today()) AND (table LIKE '%empty%')
ORDER BY event_time ASC
FORMAT PrettyCompactMonoBlock

┌─event_type─┬──────────event_time─┬─table───────────┬─part_name─┬─rows─┐
│ NewPart    │ 2021-02-10 21:27:40 │ .inner.empty_mv │ all_1_1_0 │    0 │
│ RemovePart │ 2021-02-10 21:27:42 │ .inner.empty_mv │ all_1_1_0 │    0 │
│ NewPart    │ 2021-02-10 21:46:42 │ .inner.empty_mv │ all_2_2_0 │    1 │
└────────────┴─────────────────────┴─────────────────┴───────────┴──────┘
```
ttl_info.update(column_const->getValue<UInt32>());
        }
        else
            throw Exception("Unexpected type of result TTL column", ErrorCodes::LOGICAL_ERROR);
    }
    else
        throw Exception("Unexpected type of result TTL column", ErrorCodes::LOGICAL_ERROR);
    if (update_part_min_max_ttls)
        ttl_infos.updatePartMinMaxTTL(ttl_info.min, ttl_info.max);
}
}
BlocksWithPartition MergeTreeDataWriter::splitBlockIntoParts(const Block & block, size_t max_parts, const StorageMetadataPtr & metadata_snapshot)
{
    BlocksWithPartition result;
    if (!block || !block.rows())
        return result;
    metadata_snapshot->check(block, true);
    if (!metadata_snapshot->hasPartitionKey()) 
    {
        result.emplace_back(Block(block), Row());
        return result;
    }
    Block block_copy = block;
    const auto & partition_key = metadata_snapshot->getPartitionKey();
    partition_key.expression->execute(block_copy);
    ColumnRawPtrs partition_columns;
    partition_columns.reserve(partition_key.sample_block.columns());
    for (const ColumnWithTypeAndName & element : partition_key.sample_block)
        partition_columns.emplace_back(block_copy.getByName(element.name).column.get());
    PODArray<size_t> partition_num_to_first_row;