Getting total View entries including categories - performance issue

佐手、 提交于 2019-12-13 04:28:49

问题


I'm using a custom footer on my View Control; there I have for example:

Displaying 1 - 25 of 34200

My underlying View is Categorized so the total of entries should include categories as well. So far the only way I'm able to find the total of entries including categories is using NotesViewNavigator; however, performance is not acceptable since it's taking around 27 seconds to compute this piece of code.

I'm sure the issue is with line var nav:NotesViewNavigator = view1.createViewNav(); because I added some debugger info:

start = new Date().getTime();
var viewPanel1:com.ibm.xsp.component.xp.XspViewPanel = getComponent("dataView1");
var nav:NotesViewNavigator = view1.createViewNav();
if (viewScope.VendorSrch == "" || viewScope.VendorSrch == null){
    var total =  nav.getCount(); 
}else{          
    var total = viewPanel1.getRowCount();// View can be filtered by user as well (using categoryFilter property)
}

var from =(viewPanel1.getFirst() < total? (viewPanel1.getFirst() + 1 ) : total);
var tmpTo = viewPanel1.getFirst() + viewPanel1.getRows();
var to = (tmpTo < total? tmpTo : total);

var elapsed = new Date().getTime() - start;
print(elapsed + " ms");
"</b>Displaying <b>"+ from +"</b> - <b>"+ to + "</b> of " + "<b>"+total+"</b>"

Does anyone know how can I improve this piece of code?

Please note documents in this View have Readers fields as well which may be impacting the performance of this operation.


回答1:


You are trapped in performance hell. Read access protection is only and only stored inside the document. So when you ask your view navigator to get the count its only option is to open all involved documents - hence the poor performance. Read protection and performance are natural enemies (just imagine: you have an office where every door is locked and to move around you have to check all your keys every time if you have one with the matching lock number).

The way out of reader field introduced performance hell is to read only the entries you actually need (as outlined). It could be a little tricky if a user has access to documents based on name, group-membership and role (that would make one read per access), but it is still very much feasible. In this case you would use a repeat control and a object data source or managed bean, so the multiple passes happen in the background.

Bonus trick: if you add a column with the formula 1 (just the number) and add it up, while categorizing it, then you can just jump from naventry to next sibling (that would be the next category) and add the numbers --> much less reads involved and NO documents opened.

To stress again: nav.count needs to open all documents and is a BAD idea, anything that requires read access to be checked is a bad idea, so using one (or more) viewNav based on access rights that actually only read documents the user can read is the way to go.

Let me know if you need more hints




回答2:


I tried several approaches and using this loop reduced the time from 27 seconds average to 2.7 seconds:

start = new Date().getTime();
var viewPanel1:com.ibm.xsp.component.xp.XspViewPanel = getComponent("dataView1");
var nav:NotesViewNavigator = view1.createViewNav();
nav.setEntryOptions(NotesViewNavigator.VN_ENTRYOPT_NOCOLUMNVALUES);

// disable autoupdate
view1.setAutoUpdate(false);
if (viewScope.VendorSrch == "" || viewScope.VendorSrch == null){
    nav.setBufferMaxEntries(400);       
    //var total =  nav.getCount(); // This works but slow

    // peform lookup
    var vwentry:NotesViewEntry = nav.getFirst();
    var vwentrytmp:NotesViewEntry = null;
    count = 0;
    while (vwentry != null){
        count = count + 1;       
        // Get entry and go recycle
        vwentrytmp = nav.getNext(vwentry);
        vwentry.recycle();
        vwentry = vwentrytmp;        
    }

    total = count;

}else{  
    var total = viewPanel1.getRowCount();   
}

var from =(viewPanel1.getFirst() < total? (viewPanel1.getFirst() + 1 ) : total);
var tmpTo = viewPanel1.getFirst() + viewPanel1.getRows();
var to = (tmpTo < total? tmpTo : total);

var elapsed = new Date().getTime() - start;
print(elapsed + " ms");
"</b>Displaying <b>"+ from +"</b> - <b>"+ to + "</b> of " + "<b>" + total + "</b>"


来源:https://stackoverflow.com/questions/15490191/getting-total-view-entries-including-categories-performance-issue

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!