Listing all parts in log have no sense. 
Should be either silenced, either combined into a single line.
size_t num_streams_for_lonely_parts = num_streams * lonely_parts.size();
        const size_t min_marks_for_concurrent_read = minMarksForConcurrentRead(
            settings.merge_tree_min_rows_for_concurrent_read,
            settings.merge_tree_min_bytes_for_concurrent_read,
            data_settings->index_granularity,
            index_granularity_bytes,
            sum_marks_in_lonely_parts);
        
        if (sum_marks_in_lonely_parts < num_streams_for_lonely_parts * min_marks_for_concurrent_read && lonely_parts.size() < num_streams_for_lonely_parts)
            num_streams_for_lonely_parts = std::max((sum_marks_in_lonely_parts + min_marks_for_concurrent_read - 1) / min_marks_for_concurrent_read, lonely_parts.size());
        MergeTreeReadPoolPtr pool = std::make_shared<MergeTreeReadPool>(
            num_streams_for_lonely_parts,
            sum_marks_in_lonely_parts,
            min_marks_for_concurrent_read,
            std::move(lonely_parts),
            data,
            metadata_snapshot,
            query_info.prewhere_info,
            true,
            column_names,
            MergeTreeReadPool::BackoffSettings(settings),
            settings.preferred_block_size_bytes,
            false);
        LOG_TRACE(log, "Reading approx. {} rows with {} streams", total_rows_in_lonely_parts, num_streams_for_lonely_parts);
        for (size_t i = 0; i < num_streams_for_lonely_parts; ++i)
        {
            auto source = std::make_shared<MergeTreeThreadSelectBlockInputProcessor>(
                i, pool, min_marks_for_concurrent_read, max_block_size,
                settings.preferred_block_size_bytes, settings.preferred_max_column_in_block_size_bytes,
                data, metadata_snapshot, use_uncompressed_cache,