This topic describes the system architecture, key features, and use cases of MaxCompute Query Acceleration (MCQA).
MCQA (Query Acceleration 1.0) has been upgraded to MaxQA and is no longer open to new customers.
MaxCompute launched MaxQA (MaxCompute Query Accelerator 2.0) on the China site and International site on November 24, 2025 (Monday) and November 27, 2025 (Thursday) respectively (UTC+8).
To use query acceleration, see MaxQA overview and Query Acceleration MaxQA. The following content is for reference by existing MCQA users only.
Introduction
MaxCompute MCQA provides the following capabilities:
Accelerates queries on small-to-medium datasets, reducing execution times from minutes to seconds. Fully compatible with existing MaxCompute query features.
Supports mainstream BI tools for ad hoc queries and BI analysis.
Uses independent resource pools without consuming offline computing resources. Automatically identifies query jobs to reduce queuing pressure.
Caches MCQA query results in a temporary cache. When the same query runs again, MaxCompute returns cached results for faster execution.
Query flow
The following figure shows the MaxCompute query processing architecture. After a query is received, smart routing directs it to one of three paths: Query Acceleration (MCQA), standard SQL execution, or multi-engine computing.
In this architecture, MCQA writes query results to a temporary cache. When the same query runs again, MaxCompute returns cached results for faster execution. Caching mechanism.
Use cases
Scenario | Description | Characteristics |
Ad hoc queries | Optimizes query performance on small-to-medium datasets (up to hundreds of GB) with low latency for rapid data development and analysis. |
|
Business Intelligence (BI) | For enterprise data warehouses on MaxCompute where ETL produces business-ready aggregations. MCQA's low latency, elastic concurrency, and caching, combined with partitioning and bucketing, cost-effectively support concurrent reporting and analytics. |
|
Large-scale data exploration | MCQA automatically identifies query characteristics, handles small jobs with fast response, and scales resources for larger jobs to meet varying analysis needs. |
|
Scope
Version requirements:
MaxCompute client (odpscmd): v0.40.8 or later.
ODPS-JDBC: v3.3.0 or later.
ODPS-SDK: v0.40.8-public or later.
Only data query (SELECT) statements are supported. If an unsupported statement is submitted, the MaxCompute client, JDBC, and SDK can fall back to standard offline mode. Other tools do not support fallback. After a query falls back to standard SQL, it is billed under the original SQL billing model.
Row limit: The default maximum is 1,000,000 rows. Add a LIMIT keyword to your SQL statement to exceed this limit.
Feature restrictions:
Restriction
Description
Features
Supported: Standard edition and pay-as-you-go MaxCompute.
Supported: Subscription billing.
Not supported: Developer edition. Upgrade to Standard edition required.
Queries
Maximum 2,000 concurrent workers per job.
Default timeout: 30s for client-submitted jobs, 20s for DataWorks ad hoc queries. After timeout, jobs fall back to standard query mode.
Only tables in ALIORC storage format can be cached in memory for acceleration.
Query concurrency
Subscription mode:
Free tier (no MCQA interactive resource group allocated):
Maximum 5 concurrent jobs per project per day, up to 500 jobs total per project per day. Excess jobs automatically fall back to standard mode. If fallback is disabled, the following error is returned:
ODPS-1800001: Session exception - Failed to submit sub-query in session because:Prepaid project run outoffree query quota.MCQA interactive resource group:
Maximum 120 concurrent MCQA jobs per project. Excess jobs fall back to standard mode.
The reserved CU minimum must equal the reserved CU maximum for the interactive resource quota group. Otherwise the configuration does not take effect.
Interactive resource type requirements (jobs are rejected if not met):
Reserved CU [minCU]=Reserved CU [maxCU].Reserved CU must be ≥
50CU.
After configuring an interactive resource quota group, all projects only support submitting acceleration-eligible jobs to the interactive quota group. The free MCQA trial is no longer available.
Interactive resource quota groups cannot serve as the default quota for a project. When using MCQA, the interactive quota group takes effect for all projects without explicit binding.
Pay-as-you-go mode:
Maximum 120 concurrent MCQA jobs per MaxCompute project. Excess jobs fall back to standard mode.
Caching mechanism
For each MCQA query, MaxCompute creates a temporary dataset to cache the results. The cache size limit is 10 GB per temporary dataset.
The owner of the temporary dataset is the user who ran the query and generated the cached results.
The temporary dataset is invisible to users and cannot be viewed.
MaxCompute automatically grants the query-executing user access to the temporary dataset.
To retrieve cached results, the query and context configuration must be identical to the original query. MaxCompute reuses cached results for duplicate queries.
Cache billing
Cached query results incur no storage or compute charges, effectively reducing resource usage costs.
Cache eviction
MaxCompute deletes cached results when:
Project resource utilization is high — MaxCompute may evict cached results early.
Referenced tables or views change — cached results are invalidated immediately. Rerunning the same query will not retrieve cached data.
Cached results have expired.
Cache verification
Logview 2.0 provides query job Logview information. On the Job Details tab, you can verify that query results have been written to cache:
In the Progress Chart view, the RESULTCACHE node shows R/W of 0/0 rows, indicating results were retrieved from cache.
Enable MCQA for subscription plans
Procedure
Follow these steps to enable MCQA for a subscription MaxCompute instance:
The subscription MCQA quota determines scan concurrency, which affects the data volume scanned. Approximately 1 CU scans 0.6 GB. For example, 50 CU supports scanning about 30 GB simultaneously, with a maximum of 300 GB.
Log in to the MaxCompute console and select a region in the upper-left corner.
In the left-side navigation pane, choose .
On the Quotas page, click Quota Configuration in the Actions column of the target quota.
Quota basic configuration
On the Quota Configuration page, select the Basic Configurations tab and click Edit Basic Configurations.
Click Add Level-2 Quota, or configure basic parameters for an existing level-2 quota.
Set a custom Quota Name and select Interactive for Type. Configure quotas.
Quota scaling configuration
On the Quota Configuration page, select the Scaling Configuration tab.
On the Scaling Configuration tab, click Add Configuration Plan, or click Edit in the Actions column of an existing plan to update it.
In the Add Configuration Plan or Edit Configuration Plan dialog box, configure Reserved CUs [minCU,maxCU] for the Interactive (MaxQA/MCQA) resource group.
minCU must equal maxCU.
minCU must be ≥
50CU. Set to0if interactive resources are not needed.Interactive quota groups do not support elastic reserved CU.
Click OK to save the quota configuration.
On the Scaling Configuration tab, click Apply Immediately in the Actions column of the target plan to apply it immediately. You can also use existing plans when configuring Scheduled Scaling Management.
Configure time plans.
Time plans let you apply different quota configurations at different times of day.
Scheduling policy
Interactive quota groups are automatically scheduled by the server. The scheduling policy depends on the number of interactive quota groups in your tenant:
Single interactive quota group: all MCQA jobs in the tenant are scheduled to this group.
Multiple interactive quota groups: auto-routing selects the group based on your configuration. Using quotas for computing resources.
Fallback policy
When MCQA jobs fall back to standard query mode due to usage restrictions, subscription plans use the quota bound to the current project.
Use the SDK (higher than v0.40.7) to specify the fallback execution quota:
SQLExecutorBuilder builder = SQLExecutorBuilder.builder(); builder.quotaName("<OfflineQuotaName>");Use the JDBC connection string parameter
fallbackQuota=XXXto specify the fallback execution quota. You cannot specify an interactive quota group as the fallback target; doing so causes an error.
MCQA access methods
MCQA supports the following access methods:
Method 1: Enable MCQA via the MaxCompute client
Download the latest MaxCompute client (odpscmd).
Install and configure the client. Install and configure odpscmd.
Edit the configuration file
odps_config.iniin theconfdirectory of the client installation path. Add the following settings:enable_interactive_mode=true -- Enable MCQA interactive_auto_rerun=true -- Auto-fallback to standard mode on MCQA failureRun the MaxCompute client from the
bindirectory (Linux:./bin/odpscmd, Windows:./bin/odpscmd.bat). A successful connection outputs:Aliyun ODPS Command Line Tool Version 0.35.1-public Connecting to http://service.cn-hangzhou.maxcompute.aliyun.com/api, project: Project timezone: Asia/Shanghai Connected!After running a query, if the Logview in the returned results contains MCQA-related information, the feature is enabled. On the Summary tab of LogView, if
Job run mode: session job 2.0is shown, MCQA (interactive) mode is active.
Method 2: Enable MCQA via DataWorks ad hoc queries or data development
DataWorks ad hoc queries and manual workflow modules have MCQA enabled by default.
Run a query in Ad Hoc Query. If MCQA is active, the run log shows
Congratulations! Your task was selected to run in MaxCompute query acceleration modeandMaxCompute query acceleration mode ran SQL successfully.Run a query in Manual Workflow. The run log shows
Congratulations! Your task was selected to run in MaxCompute query acceleration modeandMaxCompute query acceleration mode ran SQL successfully.
Method 3: Enable MCQA via JDBC
Connect to MaxCompute via JDBC and enable MCQA. JDBC reference.
Download the MCQA-compatible JDBC_JAR or compilable source code.
Configure POM dependency via Maven.
<dependency> <groupId>com.aliyun.odps</groupId> <artifactId>odps-jdbc</artifactId> <version>3.3.0</version> <classifier>jar-with-dependencies</classifier> </dependency>Create a Java program based on the source code. Adapt it to your configuration. MaxCompute JDBC. Example:
// An Alibaba Cloud account AccessKey has access to all API operations, which poses a high security risk. // We strongly recommend that you create and use a RAM user for API access or routine O&M. Log on to the RAM console to create a RAM user. // This example uses AccessKey and AccessKeySecret stored in environment variables. // You can also store them in a configuration file based on your business requirements. // We strongly recommend that you do not save the AccessKey and AccessKeySecret in your code. This may cause the AccessKey pair to be leaked. private static String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"); private static String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"); // your_project_name is the name of the project for which you want to enable MCQA. String conn = "jdbc:odps:http://service.<regionid>.maxcompute.aliyun.com/api?project=<YOUR_PROJECT_NAME>"&accessId&accessKey&charset=UTF-8&interactiveMode=true&alwaysFallback=false&autoSelectLimit=1000000000"; Statement stmt = conn.createStatement(); Connection conn = DriverManager.getConnection(conn, accessId, accessKey); Statement stmt = conn.createStatement(); String tableName = "testOdpsDriverTable"; stmt.execute("DROP TABLE IF EXISTS " + tableName); stmt.execute("CREATE TABLE " + tableName + " (key int, value string)");You can configure the following parameters in the connection string:
Parameter
Description
enableOdpsLogger
Enables logging. Set to True when SLF4J is not configured.
fallbackForUnknownError
Default: False. Set to True to fall back to offline mode on unknown errors.
fallbackForResourceNotEnough
Default: False. Set to True to fall back to offline mode on insufficient resources.
fallbackForUpgrading
Default: False. Set to True to fall back to offline mode during upgrades.
fallbackForRunningTimeout
Default: False. Set to True to fall back to offline mode on execution timeout.
fallbackForUnsupportedFeature
Default: False. Set to True to fall back to offline mode for unsupported MCQA scenarios.
alwaysFallback
Default: False. Set to True to fall back to offline mode in all above scenarios. Requires JDBC 3.2.3 or later.
Usage examples
Example 1: Use MCQA with Tableau:
Add
interactiveMode=trueto the server URL to enable MCQA. Also addenableOdpsLogger=truefor logging. Configure MaxCompute JDBC on Tableau.Full server configuration example:
http://service.cn-beijing.maxcompute.aliyun.com/api? project=****_beijing&interactiveMode=true&enableOdpsLogger=true&autoSelectLimit=1000000000"To limit Tableau to specific tables, add
table_list=table_name1, table_name2to the server URL (comma-separated). Too many tables may slow Tableau loading. For heavily partitioned tables, filter partitions or use custom SQL. Example:http://service.cn-beijing.maxcompute.aliyun.com/api?project=****_beijing &interactiveMode=true&alwaysFallback=true&enableOdpsLogger=true&autoSelectLimit=1000000000" &table_list=orders,customersExample 2: Use MCQA with SQLWorkbench.
After configuring the JDBC driver, modify the JDBC URL in the Profile settings. Configure MaxCompute JDBC on SQL Workbench/J.
URL format:
jdbc:odps:<MaxCompute_endpoint>? project=<MaxCompute_project_name>&accessId=<AccessKey ID>&accessKey=<AccessKey Secret> &charset=UTF-8&interactiveMode=true&autoSelectLimit=1000000000"Parameter descriptions:
Parameter
Description
MaxCompute_endpoint
The endpoint of the region where MaxCompute runs. Endpoint.
MaxCompute_project_name
MaxCompute project name.
AccessKey ID
AccessKey ID with access to the specified project.
Obtain it from the AccessKey management page.
AccessKey Secret
The AccessKey Secret for the AccessKey ID.
Obtain it from the AccessKey management page.
charset=UTF-8
Character encoding format.
interactiveMode
MCQA toggle. Set
trueto enable MCQA.autoSelectLimit
Required when data exceeds the 1,000,000-row limit.
Method 4: Enable MCQA via Java SDK
Java SDK overview. Configure POM dependency via Maven:
<dependency>
<groupId>com.aliyun.odps</groupId>
<artifactId>odps-sdk-core</artifactId>
<version>3.3.0</version>
</dependency>import com.aliyun.odps.Odps;
import com.aliyun.odps.OdpsException;
import com.aliyun.odps.OdpsType;
import com.aliyun.odps.account.Account;
import com.aliyun.odps.account.AliyunAccount;
import com.aliyun.odps.data.Record;
import com.aliyun.odps.data.ResultSet;
import com.aliyun.odps.sqa.*;
import java.io.IOException;
import java.util.*;
public class SQLExecutorExample {
public static void SimpleExample() {
// Set account and project information.
// An Alibaba Cloud account AccessKey has access to all API operations, which poses a high security risk.
// We strongly recommend that you create and use a RAM user for API access or routine O&M. Log on to the RAM console to create a RAM user.
// This example uses AccessKey and AccessKeySecret stored in environment variables. You can also store them in a configuration file based on your business requirements.
// We strongly recommend that you do not save the AccessKey and AccessKeySecret in your code. This may cause the AccessKey pair to be leaked.
Account account = new AliyunAccount(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
Odps odps = new Odps(account);
odps.setDefaultProject("<YOUR_PROJECT_NAME>");
odps.setEndpoint("http://service.<regionid>.maxcompute.aliyun.com/api");
// Prepare to build an SQLExecutor.
SQLExecutorBuilder builder = SQLExecutorBuilder.builder();
SQLExecutor sqlExecutor = null;
try {
// run in offline mode or run in interactive mode
if (false) {
// Create an Executor that runs offline SQL by default.
sqlExecutor = builder.odps(odps).executeMode(ExecuteMode.OFFLINE).build();
} else {
// Create an Executor that runs SQL in query acceleration mode by default and automatically falls back to offline mode on failure.
sqlExecutor = builder.odps(odps).executeMode(ExecuteMode.INTERACTIVE).fallbackPolicy(FallbackPolicy.alwaysFallbackPolicy()).build();
}
// Pass custom query settings if needed.
Map<String, String> queryHint = new HashMap<>();
queryHint.put("odps.sql.mapper.split.size", "128");
// Submit a query job. Hints are supported.
sqlExecutor.run("select count(1) from test_table;", queryHint);
// List commonly used methods for retrieving information.
// UUID
System.out.println("ExecutorId:" + sqlExecutor.getId());
// Logview of the current query job.
System.out.println("Logview:" + sqlExecutor.getLogView());
// Instance object of the current query job (in Interactive mode, multiple query jobs may share the same Instance).
System.out.println("InstanceId:" + sqlExecutor.getInstance().getId());
// Stage progress of the current query job (console progress bar).
System.out.println("QueryStageProgress:" + sqlExecutor.getProgress());
// Execution status change log of the current query job, such as fallback information.
System.out.println("QueryExecutionLog:" + sqlExecutor.getExecutionLog());
// Two methods are provided for retrieving results.
if(false) {
// Retrieve all query results at once. This synchronous method may block the current thread until the query succeeds or fails.
// Reads all result data into memory at once. Not recommended for large datasets due to potential memory issues.
List<Record> records = sqlExecutor.getResult();
printRecords(records);
} else {
// Retrieve a ResultSet iterator for query results. This synchronous method may block the current thread until the query succeeds or fails.
// Recommended for large result sets. Reads query results in batches.
ResultSet resultSet = sqlExecutor.getResultSet();
while (resultSet.hasNext()) {
printRecord(resultSet.next());
}
}
// run another query
sqlExecutor.run("select * from test_table;", new HashMap<>());
if(false) {
// Retrieve all query results at once. This synchronous method may block the current thread until the query succeeds or fails.
// Reads all result data into memory at once. Not recommended for large datasets due to potential memory issues.
List<Record> records = sqlExecutor.getResult();
printRecords(records);
} else {
// Retrieve a ResultSet iterator for query results. This synchronous method may block the current thread until the query succeeds or fails.
// Recommended for large result sets. Reads query results in batches.
ResultSet resultSet = sqlExecutor.getResultSet();
while (resultSet.hasNext()) {
printRecord(resultSet.next());
}
}
} catch (OdpsException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (sqlExecutor != null) {
// Close the Executor to release resources.
sqlExecutor.close();
}
}
}
// SQLExecutor can be reused by pool mode
public static void ExampleWithPool() {
// Execute queries using a connection pool.
// An Alibaba Cloud account AccessKey has access to all API operations, which poses a high security risk.
// We strongly recommend that you create and use a RAM user for API access or routine O&M. Log on to the RAM console to create a RAM user.
// This example uses AccessKey and AccessKeySecret stored in environment variables. You can also store them in a configuration file based on your business requirements.
// We strongly recommend that you do not save the AccessKey and AccessKeySecret in your code. This may cause the AccessKey pair to be leaked.
Account account = new AliyunAccount(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
Odps odps = new Odps(account);
odps.setDefaultProject("your_project_name");
odps.setEndpoint("http://service.<regionid>.maxcompute.aliyun.com/api");
// Prepare a connection pool and set the pool size and default execution mode.
SQLExecutorPool sqlExecutorPool = null;
SQLExecutor sqlExecutor = null;
try {
// Prepare a connection pool and set the pool size and default execution mode.
SQLExecutorPoolBuilder builder = SQLExecutorPoolBuilder.builder();
builder.odps(odps)
.initPoolSize(1) // init pool executor number
.maxPoolSize(5) // max executors in pool
.executeMode(ExecuteMode.INTERACTIVE); // run in interactive mode
sqlExecutorPool = builder.build();
// Get an Executor from the connection pool. If none is available, a new one is created within the maximum limit.
sqlExecutor = sqlExecutorPool.getExecutor();
// The Executor usage is the same as in the previous example.
sqlExecutor.run("select count(1) from test_table;", new HashMap<>());
System.out.println("InstanceId:" + sqlExecutor.getId());
System.out.println("Logview:" + sqlExecutor.getLogView());
List<Record> records = sqlExecutor.getResult();
printRecords(records);
} catch (OdpsException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
sqlExecutor.close();
}
sqlExecutorPool.close();
}
private static void printRecord(Record record) {
for (int k = 0; k < record.getColumnCount(); k++) {
if (k != 0) {
System.out.print("\t");
}
if (record.getColumns()[k].getType().equals(OdpsType.STRING)) {
System.out.print(record.getString(k));
} else if (record.getColumns()[k].getType().equals(OdpsType.BIGINT)) {
System.out.print(record.getBigint(k));
} else {
System.out.print(record.get(k));
}
}
}
private static void printRecords(List<Record> records) {
for (Record record : records) {
printRecord(record);
System.out.println();
}
}
public static void main(String args[]) {
SimpleExample();
ExampleWithPool();
}
}Method 5: Enable MCQA via PyODPS with SQLAlchemy or other SQLAlchemy-compatible tools
PyODPS integrates SQLAlchemy for querying MaxCompute data. Specify the following parameters in the connection string to enable MCQA:
interactive_mode=true: Required. MCQA master switch.reuse_odps=true: Optional. Forces connection reuse. Improves performance with some third-party tools (e.g., Apache Superset).
Configure fallback_policy=<policy1>,<policy2>,... in the connection string to control fallback behavior, similar to JDBC parameters.
generic: Default: False. Falls back to offline mode on unknown errors.noresource: Default: False. Falls back to offline mode on insufficient resources.upgrading: Default: False. Falls back to offline mode during upgrades.timeout: Default: False. Falls back to offline mode on execution timeout.unsupported: Default: False. Falls back to offline mode for unsupported MCQA scenarios.default: Equivalent to specifying unsupported, upgrading, noresource, and timeout. This is the default iffallback_policyis not specified.all: Default: False. Falls back to offline mode in all above scenarios.
Usage example
Connection string with MCQA enabled, forced connection reuse, and fallback for unsupported/upgrading/noresource scenarios:
odps://<access_id>:<ACCESS_KEY>@<project>/?endpoint=<endpoint>&interactive_mode=true&reuse_odps=true&fallback_policy=unsupported,upgrading,noresourceFAQ
Q1: When using JDBC to connect to MaxCompute and executing SQL tasks with subscription resources, error ODPS-1800001 occurs:
sError:com.aliyun.odps.OdpsException: ODPS-1800001: Session exception - Failed to submit sub-query in session because:Prepaid project run out of free query quota.Possible cause:
During the MCQA public preview, subscription plan users can try MCQA for free. The free trial allows a maximum of 5 concurrent MCQA jobs per project and up to 500 free accelerated jobs per project per day. Exceeding 500 jobs triggers this error.
Solution:
Set
alwaysFallback=truein the JDBC MCQA configuration. Jobs within the 500 limit use MCQA; excess jobs fall back to offline mode. MCQA access methods.
Q2: PyODPS request-response times are longer than DataWorks.
Possible causes:
Using
wait_for_xxxmethods, which add latency.Long polling intervals.
Solutions:
For fast-running requests, skip
wait_for_xxxmethods and use Tunnel to download results directly.Reduce polling interval:
instance.wait_for_success(interval=0.1). Example:from odps import ODPS, errors max_retry_times = 3 def run_sql(odps, stmt): retry = 0 while retry < max_retry_times: try: inst = odps.run_sql_interactive(stmt) print(inst.get_logview_address()) inst.wait_for_success(interval=0.1) records = [] for each_record in inst.open_reader(tunnel=True): records.append(each_record) return records except errors.ODPSError as e: retry = retry + 1 print("Error: " + str(e) + " retry: " + str(retry) + "/" + str(max_retry_times)) if retry >= max_retry_times: raise e odps = ODPS(...) run_sql(odps, 'SELECT 1')
Q3: How to use Logview for troubleshooting Java SDK errors?
Solution: MaxCompute Java SDK provides a Logview interface. Use the following code to retrieve the log:
String logview = sqlExecutor.getLogView();Q4: How to get the MaxCompute Logview URL via JDBC?
Solution: MaxCompute JDBC Driver is built on the MaxCompute Java SDK. When executing SQL via JDBC, a Logview URL is generated for tracking task status and progress. Configure log output (properties.log4j) to capture the URL. By default, it prints to stdout.