docs/en/26-tdinternal/05-query.md
TDengine, as a high-performance time-series big data platform, has its querying and computing capabilities as one of the core components. The platform offers a rich set of query processing features, including not only regular aggregation queries but also advanced functions such as time-series data window queries and statistical aggregations. These query and computation tasks require close cooperation between taosc, vnode, qnode, and mnode. In a complex supertable aggregation query scenario, multiple vnodes and qnodes may need to share the responsibilities of querying and computing. For definitions and introductions of vnode, qnode, mnode, please refer to System Architecture
taosc is responsible for parsing and executing SQL. For insert-type SQL, taosc adopts a streaming read and parse strategy to improve processing efficiency. For other types of SQL, taosc first uses a syntax parser to break it down into an Abstract Syntax Tree (AST), performing preliminary syntax validation on the SQL during the parsing process. If syntax errors are found, taosc will directly return error information, along with the specific location of the error, to help users quickly locate and fix the issue.
The parsed AST is further transformed into a logical query plan, which after optimization, is converted into a physical query plan. Subsequently, taosc's scheduler converts the physical query plan into query execution tasks and sends these tasks to the selected vnode or qnode for execution. Once notified that the query results are ready, taosc retrieves the results from the respective vnode or qnode and finally returns them to the user.
The execution process of taosc can be briefly summarized as: parsing SQL into AST, generating and optimizing a logical query plan into a physical query plan, scheduling query tasks to vnode or qnode for execution, and retrieving the query results.
In the TDengine cluster, the information of supertables and the basic information of the meta-database are well managed. As the metadata server, mnode is responsible for responding to taosc's metadata query requests. When taosc needs to obtain metadata information such as vgroup, it sends a request to mnode. Upon receiving the request, mnode quickly returns the required information, ensuring that taosc can smoothly perform its operations.
Additionally, mnode is also responsible for receiving heartbeat messages sent by taosc. These heartbeat messages help maintain the connection status between taosc and mnode, ensuring unobstructed communication between the two.
In the TDengine cluster, vnode acts as a virtual node and plays a crucial role. It receives query requests distributed from physical nodes through a task queue and executes the corresponding query processing. Each vnode has its own independent task queue for managing and scheduling query requests.
When vnode receives a query request, it retrieves the request from the task queue and processes it. After processing, vnode returns the query results to the blocking query queue worker thread in the subordinate physical node, or directly back to taosc.
The executor module is responsible for implementing various query operators, which retrieve data content by calling the TSDB data reading API. The data content is returned to the executor module in the form of data blocks. TSDB is a time-series database responsible for reading the required information from memory or disk, including data blocks, data block metadata, data block statistics, and other types of information.
TSDB shields the implementation details and mechanisms of the underlying storage layer (disk and memory buffer), allowing the executor module to focus on querying and processing column-oriented data blocks. This design enables the executor module to efficiently handle various query requests while simplifying the complexity of data access and management.
In distributed database systems, the computing node executing UDF handles queries involving UDF. When a query uses UDF, the query module is responsible for scheduling the UDF Daemon to perform the UDF computation and retrieve the results.
UDF Daemon is an independent computing component responsible for executing user-defined functions. It can handle various types of data, including time-series data and tabular data. By distributing UDF computation tasks to the UDF Daemon, the query module can separate the computational load from the main query processing flow, enhancing the overall performance and scalability of the system.
During the execution of UDF, the query module works closely with the UDF Daemon to ensure the correct execution of computation tasks and the timely return of results.
To better meet user needs, the TDengine cluster provides a query policy configuration item, queryPolicy, allowing users to choose the query execution framework according to their needs. This configuration item is located in the taosc configuration file, and each configuration item is only effective for a single taosc, allowing different strategies to be mixed in different taoscs within a cluster.
The values and meanings of queryPolicy are as follows.
By selecting appropriate query strategies, users can flexibly allocate and control query resources across different nodes, achieving purposes such as computation-storage separation and pursuing ultimate performance.
TDengine significantly reduces the learning curve for users by adopting SQL as the query language. Based on standard SQL, it extends several features to better support the unique query requirements of time-series databases.
partition by clause. Users can split input data based on custom dimensions and perform any form of query operations within each group, such as constants, aggregates, scalars, expressions, etc.slimit and soffset clauses to restrict the number of groups. When limit is used together with the partition by clause, its meaning changes to a limit within the group rather than a global limit.The complete query process is as follows.
To address the need for efficient aggregation of data from different collection points in practical applications, TDengine introduces the concept of supertables. A supertable is a special table structure representing a category of data collection points with the same data schema. Essentially, a supertable is a collection of tables, each with the same field definitions but unique static tags. These tags can be multiple and can be added, deleted, or modified at any time.
Through supertables, applications can easily perform aggregation or statistical operations on all or part of the tables under a supertable by specifying tag filtering conditions. This design greatly simplifies the development process of applications, enhancing the efficiency and flexibility of data processing. The multi-table aggregation query process in TDengine is illustrated as follows:
Specific steps are as follows. Step 1, taosc retrieves metadata information about databases and tables from mnode. Step 2, mnode returns the requested metadata information. Step 3, taosc sends query requests to each vnode belonging to the supertable. Step 4, vnode initiates a local query, returning the query response after obtaining the results. Step 5, taosc sends a query request to the aggregation node (in this case, qnode). Step 6, qnode sends data request messages to each vnode to pull data. Step 7, vnode returns the query results from this node. Step 8, qnode completes multi-node data aggregation and returns the final query results to the client.
To enhance aggregation computation speed, TDengine implements separate storage of tag data and time-series data within vnode. Initially, the system filters tag data in memory to determine the set of tables involved in the aggregation operation. This significantly reduces the dataset that needs to be scanned, thereby greatly improving the speed of aggregation computation.
Additionally, thanks to the data being distributed across multiple vnodes, aggregation operations can be performed concurrently across multiple vnodes. This distributed processing approach further speeds up aggregation, enabling TDengine to handle large-scale time-series data more efficiently.
It is worth noting that aggregation queries on regular tables and most operations are also applicable to supertables, and the syntax is completely identical. For details, please refer to the manual.
To enhance the efficiency of queries and computations, caching technology plays a crucial role. TDengine fully utilizes caching technology throughout the process of querying and computing to optimize system performance.
In TDengine, caching is widely used at various stages, including data storage, query optimization, execution plan generation, and data retrieval. By caching hot data and computation results, TDengine can significantly reduce the number of accesses to the underlying storage system, lower computational overhead, and thus improve the overall efficiency of querying and computing.
Moreover, TDengine's caching mechanism also features intelligence, capable of dynamically adjusting caching strategies based on data access patterns and system load conditions. This enables TDengine to maintain good performance in the face of complex and varying query demands.
The types of data cached are as follows:
TDengine adopts corresponding caching management strategies for different types of cache objects. For metadata, RPC objects, and query objects, TDengine uses a hash cache management method. This caching management method is managed through a list, each element of which is a cache structure containing cache information, hash table, garbage collection linked list, statistics, locks, and refresh frequency.
To ensure the effectiveness of the cache and system performance, TDengine also periodically checks for expired data in the cache list through a refresh thread and deletes expired data. This regular cleaning mechanism helps avoid storing too much useless data in the cache, reducing system resource consumption while maintaining the timeliness and accuracy of cached data. The caching scheme is shown in the following image: