Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC
Open Closed

Slow Deletes with new updates #2640


User avatar
0
maharatha created

Hi -

The Delete have become slower after we upgraded from 0.13.0 to 1.4.0 in ABP.

We did the major upgrade a month back and then have been upgrading on a regular basis. But we realized today that the delete have become very slow.

We took the same delete code in both the version : old : 330 ms new : 9s

Did you guys change anything in between these versions ?


8 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Can you share a sample code for this ? Maybe including with the entity you delete if possible.

  • User Avatar
    0
    maharatha created
    public async Task MyEntrDoc(EntityDto<long> input)
            {
                MyEntrDoc myentrDoc =
                    await _myentrDocRepository.GetAsync(input.Id);
                await _myentrDocManager.DeleteAsync(input);
                await _journalEntryDocumentDetailUnitRepository.DeleteAsync(p => p.AccountingDocumentId == input.Id);
                await CurrentUnitOfWork.SaveChangesAsync();
    
                if (myentrDoc.JournalTypeId == JournalType.RecurringEntries ||
                    myentrDoc.IsRecurringEntry)
                {
                    if (myentrDoc.IsRecurringEntry)
                    {
                        if (myentrDoc.OriginalDocumentId != null)
                        {
                            var recuingJeParentEntry =
                                await
                                    _myentrDocRepository.FirstOrDefaultAsync(
                                        myentrDoc.OriginalDocumentId.Value);
                            if (!ReferenceEquals(recuingJeParentEntry, null) &&
                                !string.IsNullOrEmpty(recuingJeParentEntry.CronExpression))
                            {
                                recuingJeParentEntry.CronExpression = "";
                                await _myentrDocRepository.UpdateAsync(recuingJeParentEntry);
                            }
                            _recurringJobManager.DeleteJob(
                                $"T{AbpSession.GetTenantId()}RJ{myentrDoc.OriginalDocumentId}");
                        }
                    }
                    else
                    {
                        _recurringJobManager.DeleteJob($"T{AbpSession.GetTenantId()}RJ{myentrDoc.Id}");
                    }
                }
            }
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    It might be related to this line

    await _journalEntryDocumentDetailUnitRepository.DeleteAsync(p => p.AccountingDocumentId == input.Id);
    

    This code deletes records one by one. Do you have single record matching the expression p.AccountingDocumentId == input.Id, or is it more than one ?

  • User Avatar
    0
    maharatha created

    We have more than one record matching the below expression :

    await _journalEntryDocumentDetailUnitRepository.DeleteAsync(p => p.AccountingDocumentId == input.Id);
    

    What do you recommend ?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    If the performance is really important for you, you can use regular SQL query to delete records here or you can use batch delete libraries for entity framework.

    I know this one <a class="postlink" href="https://github.com/loresoft/EntityFramework.Extended">https://github.com/loresoft/EntityFramework.Extended</a> but we didn't try it with AspNet Zero.

  • User Avatar
    0
    maharatha created

    Hi -

    While debugging the source code for ABP we found this :

    Abp Ticket : <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1617">https://github.com/aspnetboilerplate/as ... ssues/1617</a> Blame : <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blame/6076a126f975ea1721348f24c89ed7b44e9f2d6e/src/Abp.EntityFramework/EntityFramework/AbpDbContext.cs">https://github.com/aspnetboilerplate/as ... Context.cs</a> Source file : <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1617">https://github.com/aspnetboilerplate/as ... ssues/1617</a>

    You are reloading befoire doing a soft delete :

    softDeleteEntry.Reload();

    This is causing a select query to fire before deletion. So when we delete 3000 records it fires 3000 select statements and then 3000 update statements to delete the records.

    I don't see the need of Reload for everyone, can we come up with a different solution ?

    Thanks, Partha

  • User Avatar
    0
    maharatha created

    Can i get a response on this?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    First of all, sorry for the late response.

    You can write your comment about it here <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1617">https://github.com/aspnetboilerplate/as ... ssues/1617</a> and we will consider it.

    For the solution of your problem, even if the entity is not reloaded, it might not be a good way to delete each 3000 entity one by one. I think, it is better to use a custom code to delete all 3000 entities maybe with a custom repository and custom sql query.

    Thanks.