diff --git a/sw/source/ui/dbui/dbmgr.cxx b/sw/source/ui/dbui/dbmgr.cxx
index 34ad7f2..6e0c1c2 100644
--- a/sw/source/ui/dbui/dbmgr.cxx
+++ b/sw/source/ui/dbui/dbmgr.cxx
@@ -3127,27 +3127,28 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
     pImpl->pMergeData = new SwDSParam(
                 rMMConfig.GetCurrentDBData(), xResultSet, rMMConfig.GetSelection());
 
+    SwDSParam* pMergeData = pImpl->pMergeData;
     try{
         //set to start position
-        if(pImpl->pMergeData->aSelection.getLength())
+        if(pMergeData->aSelection.getLength())
         {
             sal_Int32 nPos = 0;
-            pImpl->pMergeData->aSelection.getConstArray()[ pImpl->pMergeData->nSelectionIndex++ ] >>= nPos;
-            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->absolute( nPos );
-            pImpl->pMergeData->CheckEndOfDB();
-            if(pImpl->pMergeData->nSelectionIndex >= pImpl->pMergeData->aSelection.getLength())
-                pImpl->pMergeData->bEndOfDB = TRUE;
+            pMergeData->aSelection.getConstArray()[ pMergeData->nSelectionIndex++ ] >>= nPos;
+            pMergeData->bEndOfDB = !pMergeData->xResultSet->absolute( nPos );
+            pMergeData->CheckEndOfDB();
+            if(pMergeData->nSelectionIndex >= pMergeData->aSelection.getLength())
+                pMergeData->bEndOfDB = TRUE;
         }
         else
         {
-            pImpl->pMergeData->bEndOfDB = !pImpl->pMergeData->xResultSet->first();
-            pImpl->pMergeData->CheckEndOfDB();
+            pMergeData->bEndOfDB = !pMergeData->xResultSet->first();
+            pMergeData->CheckEndOfDB();
         }
     }
     catch(Exception&)
     {
-        pImpl->pMergeData->bEndOfDB = TRUE;
-        pImpl->pMergeData->CheckEndOfDB();
+        pMergeData->bEndOfDB = TRUE;
+        pMergeData->CheckEndOfDB();
         DBG_ERROR("exception in MergeNew()")
     }
 
@@ -3226,44 +3227,41 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
         long nStartRow, nEndRow;
         ULONG nDocNo = 1;
         sal_Int32 nDocCount = 0;
-        if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pImpl->pMergeData->xResultSet ) )
+        if( !IsMergeSilent() && lcl_getCountFromResultSet( nDocCount, pMergeData->xResultSet ) )
             aMonitorDlg.SetTotalCount( nDocCount );
 
-        do
+        // create a new docshell from the temporary document
+        SfxBoolItem aHidden( SID_HIDDEN, TRUE );
+        SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii(URL_PREFIX_PRIV_SOFFICE ));
+        SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
+        SfxStringItem aURL( SID_FILE_NAME, sSourceDocURL );
+        const SfxPoolItem* pReturnValue =
+          rSourceView.GetViewFrame()->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON,
+                                                                &aURL, &aFilterName, &aHidden, &aReferer, &aTarget, 0L);
+
+        if(pReturnValue)
         {
-            nStartRow = pImpl->pMergeData->xResultSet->getRow();
-            if (!IsMergeSilent())
+            SfxViewFrameItem* pVItem = (SfxViewFrameItem*)pReturnValue;
+            SwView* pWorkView = (SwView*) pVItem->GetFrame()->GetViewShell();
+            SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
+            pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird.
+
+            // prepare workind document
+            SwDoc* pWorkDoc = rWorkShell.GetDoc();
+            SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
+            pWorkDoc->SetNewDBMgr( this );
+            pWorkDoc->EmbedAllLinks();
+            if(UNDO_UI_DELETE_INVISIBLECNTNT == rWorkShell.GetUndoIds())
+                rWorkShell.Undo();
+            do
             {
-                aMonitorDlg.SetCurrentPosition( nDocNo );
-                aMonitorDlg.Invalidate();
-                aMonitorDlg.Update();
-                // the print monitor needs some time to act
-                for( USHORT i = 0; i < 25; i++)
-                    Application::Reschedule();
-            }
+                nStartRow = pMergeData->xResultSet->getRow();
+                if (!IsMergeSilent())
+                {
+                    aMonitorDlg.SetCurrentPosition( nDocNo );
+                    aMonitorDlg.Update();
+                }
 
-            // create a new docshell from the temporary document
-            SfxBoolItem aHidden( SID_HIDDEN, TRUE );
-            SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii(URL_PREFIX_PRIV_SOFFICE ));
-            SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
-            SfxStringItem aURL( SID_FILE_NAME, sSourceDocURL );
-            const SfxPoolItem* pReturnValue =
-                            rSourceView.GetViewFrame()->GetDispatcher()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON,
-                                    &aURL, &aFilterName, &aHidden, &aReferer, &aTarget, 0L);
-            if(pReturnValue)
-            {
-                SfxViewFrameItem* pVItem = (SfxViewFrameItem*)pReturnValue;
-                SwView* pWorkView = (SwView*) pVItem->GetFrame()->GetViewShell();
-                SwWrtShell& rWorkShell = pWorkView->GetWrtShell();
-                pWorkView->AttrChangedNotify( &rWorkShell );//Damit SelectShell gerufen wird.
-
-                // merge the data
-                SwDoc* pWorkDoc = rWorkShell.GetDoc();
-                SwNewDBMgr* pWorkDBMgr = pWorkDoc->GetNewDBMgr();
-                pWorkDoc->SetNewDBMgr( this );
-                pWorkDoc->EmbedAllLinks();
-                if(UNDO_UI_DELETE_INVISIBLECNTNT == rWorkShell.GetUndoIds())
-                    rWorkShell.Undo();
                 // create a layout
                 rWorkShell.CalcLayout();
                 SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_FIELD_MERGE, rWorkShell.GetView().GetViewFrame()->GetObjectShell()));
@@ -3342,21 +3340,28 @@ sal_Int32 SwNewDBMgr::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
                 rMMConfig.AddMergedDocument( aMergeInfo );
                 ++nRet;
 
-                // the print monitor needs some time to act
-                for( USHORT i = 0; i < 25; i++)
-                    Application::Reschedule();
-
-                //restore the ole DBMgr
-                pWorkDoc->SetNewDBMgr( pWorkDBMgr );
-                //now the temporary document should be closed
-                SfxObjectShellRef xDocSh(pWorkView->GetDocShell());
-                xDocSh->DoClose();
-            }
-            nEndRow = pImpl->pMergeData->xResultSet->getRow();
-            ++nDocNo;
-        } while( !bCancel &&
+                // Undo everything on current workshell allows to loop for a
+                // merge action within the same document. It saves _loads_
+                // of times : 7 times faster than the previous way.
+                // see i40827 for more information
+                const SwNodes *pUndoNds = pWorkDoc->GetUndoNds();
+                if (pUndoNds)
+                {
+                    for( USHORT j = 0; j < pUndoNds->Count(); j++)
+                        rWorkShell.Undo();
+                }
+                nEndRow = pMergeData->xResultSet->getRow();
+                ++nDocNo;
+            } while( !bCancel &&
                 (bSynchronizedDoc && (nStartRow != nEndRow)? ExistsNextRecord() : ToNextMergeRecord()));
 
+            //restore the ole DBMgr
+            pWorkDoc->SetNewDBMgr( pWorkDBMgr );
+
+            //now the temporary document should be closed
+            SfxObjectShellRef xDocSh(pWorkView->GetDocShell());
+            xDocSh->DoClose();
+        }
         //deselect all, go out of the frame and go to the beginning of the document
         Point aPt(LONG_MIN, LONG_MIN);
         pTargetShell->SelectObj(aPt, SW_LEAVE_FRAME);
