From the table of MultiView associated types:
reference This is the reference type of the contained value. If NumDims == 1, then this is element&. Otherwise, this is the same type as template subarray::type.
template array_view::type This is the view type with Dims dimensions. It is returned by calling operator. It models MultiArray.
so they're different types, to start with. In this context, views represent a sort of subcollection of a MultiArray. They implement the MultiArray concept, but the elements they contain are actually elements of some other MultiArray. Views allow you to define a new index into the elements of a MultiArray. For example, you could define a view that reverses the index, so that the first element of the view is the last element of the MultiArray. From the documentation:
A view lets you treat a subset of the underlying elements in a MultiArray as though it were a separate MultiArray. Since a view refers to the same underlying elements, changes made to a view's elements will be reflected in the original MultiArray.
MultiArrays are defined recursively; a MultiArray of dimension n > 1 can be thought of as array of MultiArrays of dimension n-1, which are subarrays. The key difference between a subarray and a view is that you can slice a MultiArray into views of lower dimensions along any axis, including the major axis, but subarrays cannot be sliced along the major axis.
data_t d3(boost::extents[4][5][6]);
data_2d_view_t d2_view = d3[boost::indices[range(0,4,2)][1][range(0,6,3)]];
data_2d_subarray_t d2_sub = d3[1];
// the following, and anything like it, won't work
data_2d_subarray_t d2_sub_b = d3[range(0,4,2)][0];
I don't believe there's any major performance difference, though this depends on what type of index you use when creating a view. Views might be slightly less performant, but not in a big-O sense.