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 │
└────────────┴─────────────────────┴─────────────────┴───────────┴──────┘
```
{
    quorum_info.status_path = storage.zookeeper_path + "/quorum/status";
    std::future<Coordination::GetResponse> is_active_future = zookeeper->asyncTryGet(storage.replica_path + "/is_active");
    std::future<Coordination::GetResponse> host_future = zookeeper->asyncTryGet(storage.replica_path + "/host");
    
    Coordination::Stat leader_election_stat;
    zookeeper->get(storage.zookeeper_path + "/leader_election", &leader_election_stat);
    if (leader_election_stat.numChildren < static_cast<int32_t>(quorum))
        throw Exception("Number of alive replicas ("
            + toString(leader_election_stat.numChildren) + ") is less than requested quorum (" + toString(quorum) + ").",
            ErrorCodes::TOO_FEW_LIVE_REPLICAS);
    /** Is there a quorum for the last part for which a quorum is needed?
        * Write of all the parts with the included quorum is linearly ordered.
        * This means that at any time there can be only one part,
        *  for which you need, but not yet reach the quorum.
        * Information about this part will be located in `/quorum/status` node.
        * If the quorum is reached, then the node is deleted.
        */
    String quorum_status;
    if (!quorum_parallel && zookeeper->tryGet(quorum_info.status_path, quorum_status))
        throw Exception("Quorum for previous write has not been satisfied yet. Status: " + quorum_status,
                        ErrorCodes::UNSATISFIED_QUORUM_FOR_PREVIOUS_WRITE);
    
    auto is_active = is_active_future.get();