diff --git a/app/code/Magento/Customer/Model/Indexer/Source.php b/app/code/Magento/Customer/Model/Indexer/Source.php
new file mode 100644
index 0000000000000000000000000000000000000000..60522227eb222fb058c3ddb36681a6276d635e94
--- /dev/null
+++ b/app/code/Magento/Customer/Model/Indexer/Source.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Customer\Model\Indexer;
+
+use Magento\Customer\Model\ResourceModel\Customer\Indexer\Collection;
+use Magento\Framework\App\ResourceConnection\SourceProviderInterface;
+use Traversable;
+
+/**
+ * Customers data batch generator for customer_grid indexer
+ */
+class Source implements \IteratorAggregate, \Countable, SourceProviderInterface
+{
+    /**
+     * @var Collection
+     */
+    private $customerCollection;
+
+    /**
+     * @var int
+     */
+    private $batchSize;
+
+    /**
+     * @param \Magento\Customer\Model\ResourceModel\Customer\Indexer\CollectionFactory $collection
+     * @param int $batchSize
+     */
+    public function __construct(
+        \Magento\Customer\Model\ResourceModel\Customer\Indexer\CollectionFactory $collectionFactory,
+        $batchSize = 10000
+    ) {
+        $this->customerCollection = $collectionFactory->create();
+        $this->batchSize = $batchSize;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMainTable()
+    {
+        return $this->customerCollection->getMainTable();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIdFieldName()
+    {
+        return $this->customerCollection->getIdFieldName();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addFieldToSelect($fieldName, $alias = null)
+    {
+        $this->customerCollection->addFieldToSelect($fieldName, $alias);
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSelect()
+    {
+        return $this->customerCollection->getSelect();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addFieldToFilter($attribute, $condition = null)
+    {
+        $this->customerCollection->addFieldToFilter($attribute, $condition);
+        return $this;
+    }
+
+    /**
+     * @return int
+     */
+    public function count()
+    {
+        return $this->customerCollection->getSize();
+    }
+
+    /**
+     * Retrieve an iterator
+     *
+     * @return Traversable
+     */
+    public function getIterator()
+    {
+        $this->customerCollection->setPageSize($this->batchSize);
+        $lastPage = $this->customerCollection->getLastPageNumber();
+        $pageNumber = 0;
+        do {
+            $this->customerCollection->clear();
+            $this->customerCollection->setCurPage($pageNumber);
+            foreach ($this->customerCollection->getItems() as $key => $value) {
+                yield $key => $value;
+            }
+            $pageNumber++;
+        } while ($pageNumber <= $lastPage);
+    }
+}
diff --git a/app/code/Magento/Customer/Model/ResourceModel/Customer/Indexer/Collection.php b/app/code/Magento/Customer/Model/ResourceModel/Customer/Indexer/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b9716af5393adb9b91de1579533b6369283d795
--- /dev/null
+++ b/app/code/Magento/Customer/Model/ResourceModel/Customer/Indexer/Collection.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Customer\Model\ResourceModel\Customer\Indexer;
+
+/**
+ * Customers collection for customer_grid indexer
+ */
+class Collection extends \Magento\Customer\Model\ResourceModel\Customer\Collection
+{
+    /**
+     * @inheritdoc
+     */
+    protected function beforeAddLoadedItem(\Magento\Framework\DataObject $item)
+    {
+        return $item;
+    }
+}
diff --git a/app/code/Magento/Customer/etc/indexer.xml b/app/code/Magento/Customer/etc/indexer.xml
index b48592cafbb20b6b62ae2e4fd953ecce1e35e0af..5f644426d81696c643324365ee7e2cacd8fb64cb 100644
--- a/app/code/Magento/Customer/etc/indexer.xml
+++ b/app/code/Magento/Customer/etc/indexer.xml
@@ -11,7 +11,7 @@
         <title translate="true">Customer Grid</title>
         <description translate="true">Rebuild Customer grid index</description>
 
-        <fieldset name="customer" source="Magento\Customer\Model\ResourceModel\Customer\Collection"
+        <fieldset name="customer" source="Magento\Customer\Model\Indexer\Source"
                   provider="Magento\Customer\Model\Indexer\AttributeProvider">
             <field name="name" xsi:type="searchable" dataType="text" handler="CustomerNameHandler"/>
             <field name="email" xsi:type="searchable" dataType="varchar"/>
diff --git a/lib/internal/Magento/Framework/Indexer/Action/Base.php b/lib/internal/Magento/Framework/Indexer/Action/Base.php
index e7edcae5d4391e27e06020eb60467b093fec05f3..d761f388456b65114ffe0e85698a1e441e82467e 100644
--- a/lib/internal/Magento/Framework/Indexer/Action/Base.php
+++ b/lib/internal/Magento/Framework/Indexer/Action/Base.php
@@ -37,11 +37,13 @@ class Base implements ActionInterface
 
     /**
      * @var AdapterInterface
+     * @deprecated
      */
     protected $connection;
 
     /**
      * @var SourceProviderInterface[]
+     * @deprecated
      */
     protected $sources;
 
@@ -52,6 +54,7 @@ class Base implements ActionInterface
 
     /**
      * @var HandlerInterface[]
+     * @deprecated
      */
     protected $handlers;
 
@@ -62,6 +65,7 @@ class Base implements ActionInterface
 
     /**
      * @var array
+     * @deprecated
      */
     protected $columnTypesMap = [
         'varchar'    => ['type' => Table::TYPE_TEXT, 'size' => 255],
@@ -71,11 +75,13 @@ class Base implements ActionInterface
 
     /**
      * @var array
+     * @deprecated
      */
     protected $filterColumns;
 
     /**
      * @var array
+     * @deprecated
      */
     protected $searchColumns;
 
@@ -96,6 +102,7 @@ class Base implements ActionInterface
 
     /**
      * @var String
+     * @deprecated
      */
     protected $string;
 
@@ -106,11 +113,13 @@ class Base implements ActionInterface
 
     /**
      * @var array
+     * @deprecated
      */
     protected $filterable = [];
 
     /**
      * @var array
+     * @deprecated
      */
     protected $searchable = [];
 
@@ -272,6 +281,7 @@ class Base implements ActionInterface
     protected function createResultCollection()
     {
         $select = $this->getPrimaryResource()->getSelect();
+        $select->reset(\Magento\Framework\DB\Select::COLUMNS);
         $select->columns($this->getPrimaryResource()->getIdFieldName());
         foreach ($this->data['fieldsets'] as $fieldset) {
             if (isset($fieldset['references'])) {
@@ -342,6 +352,8 @@ class Base implements ActionInterface
      *
      * @param array $field
      * @return void
+     *
+     * @deprecated
      */
     protected function saveFieldByType($field)
     {
diff --git a/lib/internal/Magento/Framework/Indexer/Action/Entity.php b/lib/internal/Magento/Framework/Indexer/Action/Entity.php
index e88d281fd4b819f2ff80e7bca44cd0593b300154..b8390b9d5a0022f26f7b87da980565ea4b092829 100644
--- a/lib/internal/Magento/Framework/Indexer/Action/Entity.php
+++ b/lib/internal/Magento/Framework/Indexer/Action/Entity.php
@@ -24,6 +24,6 @@ class Entity extends Base
     {
         return !count($ids)
             ? $this->createResultCollection()
-            : $this->createResultCollection()->addFieldToFilter($this->getPrimaryResource()->getRowIdFieldName(), $ids);
+            : $this->createResultCollection()->addFieldToFilter($this->getPrimaryResource()->getIdFieldName(), $ids);
     }
 }
diff --git a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php
index 31883fa8516ea112312eb897f3d0f8c0a93cfced..7d53e558287bd424afe723acf5320fb7f9a07185 100644
--- a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php
+++ b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php
@@ -10,27 +10,23 @@ class Batch
     /**
      * @param \Traversable $documents
      * @param int $size
-     * @return array
+     * @return \Generator
      */
     public function getItems(\Traversable $documents, $size)
     {
-        if (count($documents) == 0) {
-            return [];
-        }
-
         $i = 0;
-        $batch = $items = [];
+        $batch = [];
+
         foreach ($documents as $documentName => $documentValue) {
             $batch[$documentName] = $documentValue;
-            if (++$i >= $size) {
-                $items[] = $batch;
+            if (++$i == $size) {
+                yield $batch;
                 $i = 0;
                 $batch = [];
             }
         }
         if (count($batch) > 0) {
-            $items[] = $batch;
+            yield $batch;
         }
-        return $items;
     }
 }
diff --git a/lib/internal/Magento/Framework/Indexer/Test/Unit/BatchTest.php b/lib/internal/Magento/Framework/Indexer/Test/Unit/BatchTest.php
index 0df98125f9a08b7dd9a63e43fdf1070a5af693de..1571bba0a7d23ce224a7d403aa63f624f58bc313 100644
--- a/lib/internal/Magento/Framework/Indexer/Test/Unit/BatchTest.php
+++ b/lib/internal/Magento/Framework/Indexer/Test/Unit/BatchTest.php
@@ -27,7 +27,8 @@ class BatchTest extends \PHPUnit_Framework_TestCase
     public function testGetItems(array $itemsData, $size, array $expected)
     {
         $items = new \ArrayObject($itemsData);
-        $this->assertSame($expected, $this->object->getItems($items, $size));
+        $data = $this->object->getItems($items, $size);
+        $this->assertSame($expected, iterator_to_array($data));
     }
 
     /**