4D v16.3Get database measures |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v16.3
Get database measures
|
Get database measures {( options )} -> Function result | ||||||||
Parameter | Type | Description | ||||||
options | Object |
![]() |
Return options | |||||
Function result | Object |
![]() |
Object containing database measures | |||||
The Get database measures command allows you to get detailed information about 4D database engine events. Returned information includes data read/write access from/to the disk or the memory cache, as well as the use of database indexes, queries and sorts.
Get database measures returns a single object that contains all the relevant measures. The options object parameter allows you to set options for the returned information.
The returned object contains a single property named "DB" that has the following basic structure:
{
"DB": {
"diskReadBytes": {…},
"cacheReadBytes": {…},
"cacheMissBytes": {…},
"diskWriteBytes": {…},
"diskReadCount": {…},
"cacheReadCount": {…},
"cacheMissCount": {…},
"diskWriteCount": {…},
"dataSegment1": {…},
"indexSegment": {…},
"tables": {…},
"indexes": {…}
}
}
This object is made up of eight properties that contain basic measures ("diskReadBytes", "cacheReadBytes", "cacheMissBytes", "diskWriteBytes", "diskReadCount", "cacheReadCount", "cacheMissCount", "diskWriteCount") and additional properties ("dataSegment1", "indexSegment", "tables", "index") that can also contain elementary properties but at a different level and with a different scope (see below).
Note: A property is only present inside the object if it receives contents. Properties that do not have any contents are not included in the object. For example, if the database has been opened in read-only mode and indexes have not been used, the returned object will not contain "diskWriteBytes", "diskWriteCount", "indexSegment" or "indexes".
Elementary properties can be found at different levels in the DB object. They return the same information but at different scopes. Here is a description of the elementary properties:
Name | Information returned |
diskReadBytes | Bytes read from disk |
cacheReadBytes | Bytes read from cache |
cacheMissBytes | Bytes missed from cache |
diskWriteBytes | Bytes written to disk |
diskReadCount | Read accesses from disk |
cacheReadCount | Read accesses from cache |
cacheMissCount | Read accesses missed from cache |
diskWriteCount | Write accesses to disk |
The eight elementary properties all have the same object structure, for example:
"diskReadBytes": { "value": 33486473620, "history": [ // optional {"value": 52564,"time": -1665}, {"value": 54202,"time": -1649}, … ] }
The "dataSegment1" and "indexSegment" properties contain up to four elementary properties (when available):
"dataSegment1": {
"diskReadBytes": {…},
"diskWriteBytes": {…},
"diskReadCount": {…},
"diskWriteCount": {…}
},
"indexSegment": {
"diskReadBytes": {…},
"diskWriteBytes": {…},
"diskReadCount": {…},
"diskWriteCount": {…}
}
These properties return the same information as the elementary properties, but detailed for each database file:
For example, you can get the following object:
{ "DB": { "diskReadBytes": { "value": 718260 }, "diskReadCount": { "value": 229 }, "dataSegment1": { "diskReadBytes": { "value": 679092 }, "diskReadCount": { "value": 212 } }, "indexSegment": { "diskReadBytes": { "value": 39168 }, "diskReadCount": { "value": 17 } }
You can figure out how it works by adding up the returned values:
diskReadBytes.value = dataSegment1.diskReadBytes.value + indexSegment.diskReadBytes.value
diskWriteBytes.value = dataSegment1.diskWriteBytes.value + indexSegment.diskWriteBytes.value
diskReadCount.value = dataSegment1.diskReadCount.value + indexSegment.diskReadCount.value
diskWriteCount.value = dataSegment1.diskWriteCount.value + indexSegment.diskWriteCount.value
The "tables" property contains as many properties as there are tables that have been accessed either in read or write mode since the opening of the database. The name of each property is the name of the table involved. For example:
"tables": { "Employees": {…) "Companies": {…) }
Each table objects contains up to 12 properties:
{ "DB": { "tables": { "Employees": { "fields": { "CompID": { "queryCount": { "value": 3 } }, "Name": { "queryCount": { "value": 1 }, "sortCount": { "value": 3 } }, "FirstName": { "sortCount": { "value": 2 } } (...)
"queries" is an array of objects that provides a description of each query performed on the table. Each element of the array will contain three attributes:
Example: Since the moment the database was launched, a single query has been performed on the Employees table (options are with path and with history):
{ "DB": { "tables": { "Employees": { "queries": [ { "queryStatement": "(Employees.Name == ?)", "queryCount": { "value": 1, "history": [ { "value": 1, "time": -2022 } ] }, "duration": { "value": 2, "history": [ { "value": 2, "time": -2022 } ] } }, (...)
This is the most complex object. All tables that have been accessed using one or more of their indexes are stored as properties and, inside the properties, the names of the indexes used are also included as properties. Keyword indexes appear separately and their names are followed by "(Keyword)". Finally, each index name property object contains the eight elementary properties related to this index as well as up to four sub-objects depending on index use in the database since it was launched (each sub-object only exists if their corresponding operation has been performed at some point since the launch of the database).
Example: Since the moment the database was launched, several indexes of the [Employees]EmpLastName field have been solicited. In addition, 2 records were created and 16 were deleted in the [Companies] table. This table has a "name" field that is indexed. The table also has been queried and sorted using this field. The resulting object will contain:
"indexes": { "Employees": { "EmpLastName": { "diskReadBytes": {…}, "cacheReadBytes": {…}, "cacheMissBytes": {…}, "diskWriteBytes": {…}, "diskReadCount": {…}, "cacheReadCount": {…}, "cacheMissCount": {…}, "diskWriteCount": {…} } "EmpLastName (Keyword)": {...}, "index3Name": {…}, "index4Name": {…}, … } "Companies": { "Name": (...) "queryCount": { "value": 41 }, "sortCount": { "value": 3 }, "insertKeyCount": { "value": 2 }, "deleteKeyCount": { "value": 16 } table3Name: {…} }
The options parameter allows you to customize the actual information returned by the command. In options, you pass an object that can contain up to three properties: "withHistory", "historyLength", and "path".
Property | Type | Description |
"withHistory" | Boolean | "true" means the history will be returned by the function inside the returned object; "false" means the object returned by the function will not contain any history |
"historyLength" | number | Defines the size of the returned history array in seconds(*). |
"path" | string | string array | Full path of specific property or array of full paths for all specific properties that you want to get. When you pass a string, only the corresponding value is returned in the "DB" object (if the path is valid). Example: "DB.tables.Employees.records.diskWriteBytes". When you pass an array of strings, all the corresponding values are returned in the "DB" object (if the paths are valid). Example: ["DB.tables.Employee.records.diskWriteBytes", "DB.tables.Employee.records.diskReadCount","DB.dataSegment1.diskReadBytes"] |
Example: The database has just been started 20 seconds ago and the request history is 60 seconds. The returned values between 0 and -20 will be set with values or zeros, and the other ones will be set with -1. When a "-1" value is returned, this means that either the request time is too old or the value is no longer in the internal history array (i.e., the 200-item limit has been reached and older values have been removed).
This command returns information about database usage. This means that it will return a valid object with relevant values only when called:
If the command is called from a remote 4D, then the object will be left empty.
In this context, if you need to get information about the database on the server, the simplest way to perform this action is to create a method with the "Execute on server" option enabled.
This principle will also work for a component: if the component is used in a 4D local context, it will return information about the host database; in a 4D remote context, it will return information about the server database.
You want to have the history logged in the returned object:
C_OBJECT($param)
C_OBJECT($measures)
OB SET($param;"withHistory";True)
$measures:=Get database measures($param)
We only want to know the global number of bytes read in the cache ("cacheReadBytes"):
C_OBJECT($oStats)
C_OBJECT($oParams)
OB SET($oParams;"path";"DB.cacheReadBytes")
$oStats:=Get database measures($oParams)
The object returned contains, for example:
{ "DB": { "cacheReadBytes": { "value": 9516637 } } }
We want to request measures for cache bytes read within the last two minutes:
C_OBJECT($oParams)
C_OBJECT($measures)
OB SET($oParams;"path";"DB.cacheReadBytes")
OB SET($oParams;"withHistory";True)
OB SET($oParams;"historyLength";2*60)
$measures:=Get database measures($oParams)
Product: 4D
Theme: 4D Environment
Number:
1314
Created: 4D v14 R3
Modified: 4D v14 R5
4D Language Reference ( 4D v16)
4D Language Reference ( 4D v16.1)
4D Language Reference ( 4D v16.2)
4D Language Reference ( 4D v16.3)