How To: Using Search Stats OID 1.2.840.113556.1.4.970

Active Directory and LDS provide a server side control which when added to a query will provides statistics on the efficiency of the query that was executed, the specific control is OID 1.2.840.113556.1.4.970 - LDAP_SERVER_GET_STATS_OID and the details can be found here.

The NetTools LDAP Search option provides a simple checkbox option to enable this server side control to be added to queries.  The option is found in the Server Side Controls section, called Search Statistics.  When the query is run and the user has the appropriate permissions the search statistics will be returned.

When the query is executed the Statistics are displayed in the output panel after the results of the query.  Below are the statistics returned by Windows 2016 server.

The version of the operating system running on the server, will determine the statistics that will be returned.  As Windows evolved the level details returned by the server has also increased.  Windows 2000 only provided 4 different statistics, Windows 2003 increased this to 6, and for Windows 2008 this increased to 15 and it also introduced a new format which provides more details but the fields are dynamic, rather than the older static fields.

NetTools detects the Domain Controller Functional level of the server and automatically adjust the control parameters to select the highest level of detail available for the server.

The table below shows which statistics level are returned by each version of Windows

2000 2003/R2 2008/R2 2012/R2 2016 2019
StatsResponseValueV1 x
StatsResponseValueV2 x
StatsResponseValueV3 x x x x
StatsResponseValueV4 x x x x

The details for each set of Stats can be found below.  

While NetTools will automatically select the stats level based on the domain controller functional level, it is possible to manually specify the required stats level using the Server Side Controls dialog.  To do this, first uncheck the Search Statistics option, then click on the Controls button in the Server Side Control section and add a control as shown below, the Value to 1 for the corresponding V1,V2, or V3 supported by the server or a Value of 5 for the V4 stats.

These are the Statistics returned by a Windows 2019 server with the Value set to 1:

Search Stats:
  Thread Count: 1
  Call Time (ms): 0
  Entries Returned: 3
  Entries Visited: 4
  Filter: ( & (objectClass=user) (name=gary*) ) 
  Index: idx_name:4:N;
  Pages Referenced: 126
  Pages Read: 0
  Pages Pre-Read: 0
  Clean Pages Modified: 0
  Dirty Pages Modified: 0
  Log Records Generated: 0
  Log Records Bytes Generated: 0

These are the Statistics returned by the same query, with the Value set to 5

Search Stats:
  Thread count: 1
  Call time (in ms): 0
  Entries Returned: 0
  Entries Visited: 0
  Used Filter: ( & (objectClass=user) (name=gary*) ) 
  Used Indexes: idx_name:4:N;
  Pages Referenced: 27
  Pages Read From Disk: 0
  Pages Pre-read From Disk: 0
  Clean Pages Modified: 0
  Dirty Pages Modified: 0
  Log Records Generated: 0
  Log Record Bytes Generated: 0
  Indices required to optimize: 
  Query optimizer state: ( & (objectClass=user:878204) (name=gary*:4) ) 
  Atq Delay: 0
  CPU Time: 0
  Search Signature: b4cce897-7577-b624-5d18-2f5a9e90754f
  Memory Usage: 26744
  JET LV Read: 0
  JET LV Created: 0
  Total call time (in ms): 0
  Total CPU time: 0
  Number of retries: 0
  Correlation ID: e2a4641a-0714-44cc-b1bf-a0b0ca8e055c
  Links Added: 0
  Links Deleted: 0

These are the various Stats data lists:

StatsResponseValueV1 ::= SEQUENCE {
  threadCountTag            INTEGER
  threadCount               INTEGER
  coreTimeTag               INTEGER
  coreTime                  INTEGER
  callTimeTag               INTEGER
  callTime                  INTEGER
  searchSubOperationsTag    INTEGER
  searchSubOperations       INTEGER
}
StatsResponseValueV2 ::= SEQUENCE {
  threadCountTag        INTEGER
  threadCount           INTEGER
  callTimeTag           INTEGER
  callTime              INTEGER
  entriesReturnedTag    INTEGER
  entriesReturned       INTEGER
  entriesVisitedTag     INTEGER
  entriesVisited        INTEGER
  filterTag             INTEGER
  filter                OCTET STRING
  indexTag              INTEGER
  index                 OCTET STRING
 }

StatsResponseValueV3 ::= SEQUENCE {
  threadCountTag INTEGER
  threadCount INTEGER
  callTimeTag INTEGER
  callTime INTEGER
  entriesReturnedTag INTEGER
  entriesReturned INTEGER
  entriesVisitedTag INTEGER
  entriesVisited INTEGER
  filterTag INTEGER
  filter OCTET STRING
  indexTag INTEGER
  index OCTET STRING
  pagesReferencedTag INTEGER
  pagesReferenced INTEGER
  pagesReadTag INTEGER
  pagesRead INTEGER
  pagesPrereadTag INTEGER
  pagesPreread INTEGER
  pagesDirtiedTag INTEGER
  pagesDirtied INTEGER
  pagesRedirtiedTag INTEGER
  pagesRedirtied INTEGER
  logRecordCountTag INTEGER
  logRecordCount INTEGER
  logRecordBytesTag INTEGER
  logRecordBytes INTEGER
StatsResponseValueV4 ::= SEQUENCE OF SEQUENCE {
      statisticName         OCTET STRING
      CHOICE {
         intStatistic [0]       INTEGER
         stringStatistic [1]    OCTET STRING
      }
}