diff --git a/common/io/reader.go b/common/io/reader.go
index 2e4288e0e..d0c01ca3b 100644
--- a/common/io/reader.go
+++ b/common/io/reader.go
@@ -16,28 +16,50 @@ type Reader interface {
 
 // AdaptiveReader is a Reader that adjusts its reading speed automatically.
 type AdaptiveReader struct {
-	reader   io.Reader
-	allocate func() *alloc.Buffer
+	reader      io.Reader
+	largeBuffer *alloc.Buffer
+	highVolumn  bool
 }
 
 // NewAdaptiveReader creates a new AdaptiveReader.
 // The AdaptiveReader instance doesn't take the ownership of reader.
 func NewAdaptiveReader(reader io.Reader) *AdaptiveReader {
 	return &AdaptiveReader{
-		reader:   reader,
-		allocate: alloc.NewBuffer,
+		reader: reader,
 	}
 }
 
 // Read implements Reader.Read().
 func (v *AdaptiveReader) Read() (*alloc.Buffer, error) {
-	buffer := v.allocate().Clear()
+	if v.highVolumn && v.largeBuffer.IsEmpty() {
+		if v.largeBuffer == nil {
+			v.largeBuffer = alloc.NewLocalBuffer(256 * 1024).Clear()
+		}
+		nBytes, err := v.largeBuffer.FillFrom(v.reader)
+		if err != nil {
+			return nil, err
+		}
+		if nBytes < alloc.BufferSize {
+			v.highVolumn = false
+		}
+	}
+
+	buffer := alloc.NewBuffer().Clear()
+	if !v.largeBuffer.IsEmpty() {
+		buffer.FillFrom(v.largeBuffer)
+		return buffer, nil
+	}
+
 	_, err := buffer.FillFrom(v.reader)
 	if err != nil {
 		buffer.Release()
 		return nil, err
 	}
 
+	if buffer.IsFull() {
+		v.highVolumn = true
+	}
+
 	return buffer, nil
 }
 
diff --git a/common/io/reader_test.go b/common/io/reader_test.go
index 44b3cccbf..ff6eb0c8b 100644
--- a/common/io/reader_test.go
+++ b/common/io/reader_test.go
@@ -13,10 +13,17 @@ func TestAdaptiveReader(t *testing.T) {
 	assert := assert.On(t)
 
 	rawContent := make([]byte, 1024*1024)
+	buffer := bytes.NewBuffer(rawContent)
 
-	reader := NewAdaptiveReader(bytes.NewBuffer(rawContent))
+	reader := NewAdaptiveReader(buffer)
 	b1, err := reader.Read()
 	assert.Error(err).IsNil()
 	assert.Bool(b1.IsFull()).IsTrue()
 	assert.Int(b1.Len()).Equals(alloc.BufferSize)
+	assert.Int(buffer.Len()).Equals(cap(rawContent) - alloc.BufferSize)
+
+	b2, err := reader.Read()
+	assert.Error(err).IsNil()
+	assert.Bool(b2.IsFull()).IsTrue()
+	assert.Int(buffer.Len()).Equals(778272)
 }