Le 05/02/15 20:03, Emmanuel Lécharny a écrit :
> Le 04/02/15 12:53, John Peter a écrit :
>> Hi,
>>
>> I'm using apacheds 2.0.0 M_19
>>
>> ApacheDS has 11 group entries and some of them have 26 000 member
>> attributes.
>>
>> I'm using a qucik search via apache directory studio:
>> (&(member=uid=john,uid=1.2.246.1.1.1111.10.0,ou=users,dc=test,dc=fi)(objectClass=groupOfNames))
>> Using a stopwatch I can see a 5 second delay before the result is visible.
>>
>> Some other queries perform instantaneously.
>> Below is a snipet from the apacheDS log. It shows the search operation took
>> only 7070312ns or 7ms. After that apacheDS does something and the next log
>> entry is 5 seconds later.
>>
>> Any idea's what is happening?
> Ok, I can reproduce the pb.
>
> If I do a search with
>
> (member=uid=john,uid=1.2.246.1.1.1111.10.0,ou=users,dc=test,dc=fi)
>
> as a filter, it takes only 400ms, and I tested it with 32 000 members in
> the entry.
>
> If I add (objectClass=groupOfNames) it takes 14 seconds.
>
> Two things here :
> - first, you can do the search omitting the (objectClass=groupOfNames),
> because the 'member' attribute is only used by this class, unless you
> have created an ObjectClass that uses the 'member' attribute
> - second, we should be able to speed up the search when the objectClass
> is used in the filter. It seems that we don't evaluate properly the
> number of candidates the (member=XXX) part is returning. This is clearly
> a bug and need to be fixed.
Some more insights :
- when the member attribute is indexed, here is the evaluation for the
filter :

(&:[4](&:[4](member=2.5.4.3=test7438,2.5.4.11=users,2.5.4.11=system:[4])(objectClass=groupofnames:[5]))(#{SUBTREE_SCOPE
(Estimated), 'ou=system', DEREF_ALWAYS}:[15]))

It means the 'member' attribute will be used as the primary index for
the real search, and we have the 4 candidates in the result set (I have
created 5 entries, but one of them does not have the searched member).

If it's not indexed, then we will use the objectClass as the main
seelctor, but the time it will take to process it will only be slightly
longer.

- The real pb is the code that check if a specific member value is
present in the member attribute in the candidates. It does :

    private boolean evaluate( Attribute attribute ) throws LdapException
    {
        /*
         * Cycle through the attribute values testing normalized version
         * obtained from using the ordering or equality matching rule's
         * normalizer.  The test uses the comparator obtained from the
         * appropriate matching rule to perform the check.
         */
        for ( Value<?> value : attribute )
        {
            OMG !!! A loop over 32 000 values :/

If I replace this test by :

    private boolean evaluate( Attribute attribute ) throws LdapException
    {
        if ( attribute.contains( node.getValue() ) )
        {
            return true;  // A shortcut
        }

        /*
         * Cycle through the attribute values testing normalized version
         * obtained from using the ordering or equality matching rule's
         * normalizer.  The test uses the comparator obtained from the
         * appropriate matching rule to perform the check.
         */
        for ( Value<?> value : attribute )
        {

then the search is done in 45ms instead of 422 ms (10 times faster).

Still have to check what could be the impact on the whole server.






Reply via email to