Find Pinot query response format examples for selection, aggregation, and group by queries formatted in a SQL-like structure. Also find details about each field included in the Pinot broker query response.
To learn more about how a Pinot broker routes and processes queries, computes the query explain plan, and ways to optimize queries, see the following topics:
- Processing queries
- Query explain plans:
- Optimizing query routing
The query response is returned in a SQL-like tabular structure from the standard-SQL endpoint.
{% tabs %} {% tab title="Selections" %}
$ curl -H "Content-Type: application/json" -X POST \
-d '{"sql":"SELECT moo, bar, foo FROM myTable ORDER BY foo DESC"}' \
http://localhost:8099/query/sql
{
"exceptions": [],
"minConsumingFreshnessTimeMs": 0,
"numConsumingSegmentsQueried": 0,
"numDocsScanned": 6,
"numEntriesScannedInFilter": 0,
"numEntriesScannedPostFilter": 18,
"numGroupsLimitReached": false,
"numSegmentsMatched": 2,
"numSegmentsProcessed": 2,
"numSegmentsQueried": 2,
"numServersQueried": 1,
"numServersResponded": 1,
"resultTable": {
"dataSchema": {
"columnDataTypes": [
"LONG",
"INT",
"STRING"
],
"columnNames": [
"moo",
"bar",
"foo"
]
},
"rows": [
[
40015,
2019,
"xyz"
],
[
1002,
2001,
"pqr"
],
[
20555,
1988,
"pqr"
],
[
203,
2010,
"pqr"
],
[
500,
2008,
"abc"
],
[
60,
2003,
"abc"
]
]
},
"segmentStatistics": [],
"timeUsedMs": 4,
"totalDocs": 6,
"traceInfo": {}
}
{% endtab %}
{% tab title="Aggregations" %}
$ curl -X POST \
-d '{"sql":"SELECT SUM(moo), MAX(bar), COUNT(*) FROM myTable"}' \
localhost:8099/query/sql -H "Content-Type: application/json"
{
"exceptions": [],
"minConsumingFreshnessTimeMs": 0,
"numConsumingSegmentsQueried": 0,
"numDocsScanned": 6,
"numEntriesScannedInFilter": 0,
"numEntriesScannedPostFilter": 12,
"numGroupsLimitReached": false,
"numSegmentsMatched": 2,
"numSegmentsProcessed": 2,
"numSegmentsQueried": 2,
"numServersQueried": 1,
"numServersResponded": 1,
"resultTable": {
"dataSchema": {
"columnDataTypes": [
"DOUBLE",
"DOUBLE",
"LONG"
],
"columnNames": [
"sum(moo)",
"max(bar)",
"count(*)"
]
},
"rows": [
[
62335,
2019.0,
6
]
]
},
"segmentStatistics": [],
"timeUsedMs": 87,
"totalDocs": 6,
"traceInfo": {}
}
{% endtab %}
{% tab title="Group By" %}
$ curl -X POST \
-d '{"sql":"SELECT SUM(moo), MAX(bar) FROM myTable GROUP BY foo ORDER BY foo"}' \
localhost:8099/query/sql -H "Content-Type: application/json"
{
"exceptions": [],
"minConsumingFreshnessTimeMs": 0,
"numConsumingSegmentsQueried": 0,
"numDocsScanned": 6,
"numEntriesScannedInFilter": 0,
"numEntriesScannedPostFilter": 18,
"numGroupsLimitReached": false,
"numSegmentsMatched": 2,
"numSegmentsProcessed": 2,
"numSegmentsQueried": 2,
"numServersQueried": 1,
"numServersResponded": 1,
"resultTable": {
"dataSchema": {
"columnDataTypes": [
"STRING",
"DOUBLE",
"DOUBLE"
],
"columnNames": [
"foo",
"sum(moo)",
"max(bar)"
]
},
"rows": [
[
"abc",
560.0,
2008.0
],
[
"pqr",
21760.0,
2010.0
],
[
"xyz",
40015.0,
2019.0
]
]
},
"segmentStatistics": [],
"timeUsedMs": 15,
"totalDocs": 6,
"stageStats": {}
}
{% endtab %} {% endtabs %}
Response Field | Description |
---|---|
resultTable | Contains everything needed to process the response |
resultTable.dataSchema | Describes the schema of the response, including columnNames and their dataTypes |
resultTable.dataSchema.columnNames | columnNames in the response |
resultTable.dataSchema.columnDataTypes | dataTypes for each column |
resultTable.rows | Actual content with values. This is an array of arrays. The number of rows depends on the limit value in the
query. The number of columns in each row is equal to the length of resultTable.dataSchema.columnNames
|
timeUsedms | Total time taken as seen by the broker before sending the response back to the client. |
totalDocs | Number of documents/records in the table. |
numServersQueried | Represents the number of servers queried by the broker (may be less than the total number of servers since the broker can apply some optimizations to minimize the number of servers). |
numServersResponded | This should be equal to the numServersQueried . If this is not the same, then one of more servers
might have timed out. If numServersQueried != numServersResponded, the results can be considered
partial and clients can retry the query with exponential back off.
|
numSegmentsQueried | The total number of The broker decides how many segments to query on each server, based on broker pruning logic. The server decides
how many of these segments to actually look at, based on server pruning logic. After processing segments for a
query, fewer may have the matching records. |
numSegmentsMatched | The number of segments processed with at least one document matched in the query response. |
numSegmentsProcessed | The number of segment operators used to process segments. Indicates the effectiveness of the pruning logic. For more information, see query plans for: |
numDocScanned | The number of docs/records selected after the filter phase. |
numEntriesScannedInFilter | The number of entries scanned in the filtering phase of query execution. Can be larger than the total scanned doc count because of multiple filtering predicates or multi-value entries. Can also be smaller than the total scanned doc count if indexing is used for filtering. This along with |
numEntriesScannedPostFilter | The number of entries scanned after the filtering phase of query execution, ie. aggregation and/or group-by
phases. This is equivalent to This along with A high number for this means the selectivity is low (that is, Pinot needs to scan a lot of records to answer the query). If this is high, consider using star-tree index. (A regular inverted/bitmap index won't improve performance.) |
numGroupsLimitReached | If the query has a group by clause and top K, Pinot drops new entries after the numGroupsLimit
is reached. If this boolean is set to true, the query result may not be accurate. The default value for numGroupsLimit
is 100k, and should be sufficient for most use cases.
|
exceptions | Will contain the stack trace if there is any exception processing the query. |
segmentStatistics | N/A |
stageStats | In multi-stage queries, this field contains the stats for each stage. See Understanding multi-stage stats to know more about how to interpret them. |