diff --git a/src/box/index.h b/src/box/index.h
index dc5f4084d9b7f484fd169fde2e92dc9ea6a1e845..32545cdcf3afd73973377f48028e3cfa7c4aa427 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -642,9 +642,12 @@ struct index_read_view_vtab {
 	 * Look up a tuple by a full key in a read view.
 	 *
 	 * The tuple data and size are returned in the data and size arguments.
-	 * Note, the tuple may be allocated from the fiber region so one should
-	 * call region_truncate after using the data. If the key isn't found,
-	 * the data is set to NULL.
+	 * If the key isn't found, the data is set to NULL.
+	 *
+	 * Note, unless the read_view_opts::disable_decompression flag was set
+	 * at read_view_open, the returned data may be allocated on the fiber
+	 * region, and the user is supposed to call region_truncate after using
+	 * the data.
 	 *
 	 * Returns 0 on success. On error returns -1 and sets diag.
 	 */
@@ -685,9 +688,12 @@ struct index_read_view_iterator_base {
 	 * Iterate to the next tuple in the read view.
 	 *
 	 * The tuple data and size are returned in the data and size arguments.
-	 * Note, the tuple may be allocated from the fiber region so one should
-	 * call region_truncate after using the data. On EOF the data is set to
-	 * NULL.
+	 * On EOF the data is set to NULL.
+	 *
+	 * Note, unless the read_view_opts::disable_decompression flag was set
+	 * at read_view_open, the returned data may be allocated on the fiber
+	 * region, and the user is supposed to call region_truncate after using
+	 * the data.
 	 *
 	 * Returns 0 on success. On error returns -1 and sets diag.
 	 */
diff --git a/src/box/memtx_engine.cc b/src/box/memtx_engine.cc
index 64c7e0c03ca6554b023609408c95e8fc6cf99d36..faca74651fff09b70dfc09cac71fe25a8dad27fd 100644
--- a/src/box/memtx_engine.cc
+++ b/src/box/memtx_engine.cc
@@ -1652,6 +1652,7 @@ memtx_prepare_result_tuple(struct tuple **result)
 int
 memtx_prepare_read_view_tuple(struct tuple *tuple,
 			      struct memtx_tx_snapshot_cleaner *cleaner,
+			      bool disable_decompression,
 			      const char **data, uint32_t *size)
 {
 	tuple = memtx_tx_snapshot_clarify(cleaner, tuple);
@@ -1661,8 +1662,12 @@ memtx_prepare_read_view_tuple(struct tuple *tuple,
 		return 0;
 	}
 	*data = tuple_data_range(tuple, size);
-	*data = memtx_tuple_decompress_raw(*data, *data + *size, size);
-	return *data == NULL ? -1 : 0;
+	if (!disable_decompression) {
+		*data = memtx_tuple_decompress_raw(*data, *data + *size, size);
+		if (*data == NULL)
+			return -1;
+	}
+	return 0;
 }
 
 int
diff --git a/src/box/memtx_engine.h b/src/box/memtx_engine.h
index dd5ddcc8560db446b35fe300d949648172fc3f06..2fbc7468573dbff6f8f17558aa21ecb03bcd36bf 100644
--- a/src/box/memtx_engine.h
+++ b/src/box/memtx_engine.h
@@ -284,17 +284,23 @@ memtx_prepare_result_tuple(struct tuple **result);
  * to the user.
  *
  * A pointer to the raw tuple data and its size are returned in the data and
- * size out argument. The data may be allocated from the fiber region (e.g. if
- * the original tuple is compressed) so the caller should clean up the region
- * after using the data. If the tuple should be skipped (e.g. it's not visible
- * from the read view, because it was dirty when the read view was created),
- * the data is set to NULL.
+ * size out argument.
+ *
+ * This function performs two tasks:
+ *
+ *  1. Eliminates dirty tuples using the provided snapshot cleaner created
+ *     at read_view_open. If the given tuple should be skipped, the data is
+ *     set to NULL.
+ *
+ *  2. Decompresses tuples if required, unless the disable_decompression flag
+ *     is set. Decompressed tuple data is stored on the fiber region.
  *
  * Returns 0 on success. On error returns -1 and sets diag.
  */
 int
 memtx_prepare_read_view_tuple(struct tuple *tuple,
 			      struct memtx_tx_snapshot_cleaner *cleaner,
+			      bool disable_decompression,
 			      const char **data, uint32_t *size);
 
 /**
diff --git a/src/box/memtx_hash.cc b/src/box/memtx_hash.cc
index f057ee53f3e0454180fc1edf52e415f42df97e6a..23aab5584c8e22bf48358dc26e5bd5f8c09f8a1a 100644
--- a/src/box/memtx_hash.cc
+++ b/src/box/memtx_hash.cc
@@ -512,6 +512,8 @@ struct hash_read_view {
 	struct light_index_view view;
 	/** Used for clarifying read view tuples. */
 	struct memtx_tx_snapshot_cleaner cleaner;
+	/** See read_view_opts::disable_decompression. */
+	bool disable_decompression;
 };
 
 /** Read view iterator implementation. */
@@ -573,6 +575,7 @@ hash_read_view_iterator_next_raw(struct index_read_view_iterator *iterator,
 			return 0;
 		}
 		if (memtx_prepare_read_view_tuple(*res, &rv->cleaner,
+						  rv->disable_decompression,
 						  data, size) != 0)
 			return -1;
 		if (*data != NULL)
@@ -628,7 +631,6 @@ static struct index_read_view *
 memtx_hash_index_create_read_view(struct index *base,
 				  const struct read_view_opts *opts)
 {
-	(void)opts;
 	static const struct index_read_view_vtab vtab = {
 		.free = hash_read_view_free,
 		.get_raw = hash_read_view_get_raw,
@@ -643,6 +645,7 @@ memtx_hash_index_create_read_view(struct index *base,
 	}
 	struct space *space = space_cache_find(base->def->space_id);
 	memtx_tx_snapshot_cleaner_create(&rv->cleaner, space);
+	rv->disable_decompression = opts->disable_decompression;
 	rv->index = index;
 	index_ref(base);
 	light_index_view_create(&rv->view, &index->hash_table);
diff --git a/src/box/memtx_tree.cc b/src/box/memtx_tree.cc
index ccaeca70da99fa74166591c442f459756c057a41..c9e73bd550c6a01f3f1d3341b9465ebc186bbf8b 100644
--- a/src/box/memtx_tree.cc
+++ b/src/box/memtx_tree.cc
@@ -1851,6 +1851,8 @@ struct tree_read_view {
 	memtx_tree_view_t<USE_HINT> tree_view;
 	/** Used for clarifying read view tuples. */
 	struct memtx_tx_snapshot_cleaner cleaner;
+	/** See read_view_opts::disable_decompression. */
+	bool disable_decompression;
 };
 
 /** Read view iterator implementation. */
@@ -1929,6 +1931,7 @@ tree_read_view_iterator_next_raw(struct index_read_view_iterator *iterator,
 		memtx_tree_view_iterator_next(&rv->tree_view,
 					      &it->tree_iterator);
 		if (memtx_prepare_read_view_tuple(res->tuple, &rv->cleaner,
+						  rv->disable_decompression,
 						  data, size) != 0)
 			return -1;
 		if (*data != NULL)
@@ -1991,7 +1994,6 @@ static struct index_read_view *
 memtx_tree_index_create_read_view(struct index *base,
 				  const struct read_view_opts *opts)
 {
-	(void)opts;
 	static const struct index_read_view_vtab vtab = {
 		.free = tree_read_view_free<USE_HINT>,
 		.get_raw = tree_read_view_get_raw<USE_HINT>,
@@ -2007,6 +2009,7 @@ memtx_tree_index_create_read_view(struct index *base,
 	}
 	struct space *space = space_cache_find(base->def->space_id);
 	memtx_tx_snapshot_cleaner_create(&rv->cleaner, space);
+	rv->disable_decompression = opts->disable_decompression;
 	rv->index = index;
 	index_ref(base);
 	memtx_tree_view_create(&rv->tree_view, &index->tree);
diff --git a/src/box/read_view.c b/src/box/read_view.c
index 43d553cba684e0a312713559af253ef1d821d91a..0ead9cf95196f6e83ba51f2d2ac551845bc6f951 100644
--- a/src/box/read_view.c
+++ b/src/box/read_view.c
@@ -49,6 +49,7 @@ read_view_opts_create(struct read_view_opts *opts)
 	opts->enable_field_names = false;
 	opts->enable_space_upgrade = false;
 	opts->enable_temporary_spaces = false;
+	opts->disable_decompression = false;
 }
 
 static void
diff --git a/src/box/read_view.h b/src/box/read_view.h
index 998e990095fd1e558891a1598b8a989fc43e7667..ce562beb07a9f49789b76c971d37d6543a932e81 100644
--- a/src/box/read_view.h
+++ b/src/box/read_view.h
@@ -140,6 +140,15 @@ struct read_view_opts {
 	 * flag is set.
 	 */
 	bool enable_temporary_spaces;
+	/**
+	 * Memtx-specific. Disables decompression of tuples fetched from
+	 * the read view. Setting this flag makes the raw read view methods
+	 * (get_raw, next_raw) return a pointer to the data stored in
+	 * the read view as is, without any preprocessing or copying to
+	 * the fiber region. The user is supposed to decompress the data
+	 * encoded in the MP_COMPRESSION MsgPack extension manually.
+	 */
+	bool disable_decompression;
 };
 
 /** Sets read view options to default values. */