查询重写
概述
查询重写是数据库性能优化的高级技术,通过改写SQL语句的结构和逻辑,在保持结果一致的前提下提升查询性能。本文介绍各种查询重写技术和在Node.js中的实现方法。
查询重写规则
1. 子查询优化
javascript
// 子查询重写器
class SubqueryRewriter {
constructor() {
this.rewriteRules = [
{
name: 'exists_to_join',
pattern: /EXISTS\s*\(\s*SELECT.*?FROM\s+(\w+).*?WHERE.*?\)/gi,
rewriter: this.existsToJoin.bind(this)
},
{
name: 'in_to_join',
pattern: /IN\s*\(\s*SELECT.*?FROM\s+(\w+).*?\)/gi,
rewriter: this.inToJoin.bind(this)
},
{
name: 'scalar_subquery_to_join',
pattern: /SELECT.*?\(\s*SELECT.*?FROM\s+(\w+).*?\).*?FROM/gi,
rewriter: this.scalarSubqueryToJoin.bind(this)
}
];
}
// 重写查询
rewriteQuery(sql) {
let rewrittenSQL = sql;
const appliedRules = [];
for (const rule of this.rewriteRules) {
const matches = rewrittenSQL.match(rule.pattern);
if (matches) {
const newSQL = rule.rewriter(rewrittenSQL);
if (newSQL && newSQL !== rewrittenSQL) {
rewrittenSQL = newSQL;
appliedRules.push(rule.name);
}
}
}
return {
originalSQL: sql,
rewrittenSQL: rewrittenSQL,
appliedRules: appliedRules,
improved: appliedRules.length > 0
};
}
// EXISTS转JOIN
existsToJoin(sql) {
// 示例:将EXISTS子查询转换为INNER JOIN
const existsPattern = /WHERE\s+EXISTS\s*\(\s*SELECT\s+.*?\s+FROM\s+(\w+)\s+(\w+)?\s+WHERE\s+(.*?)\)/gi;
return sql.replace(existsPattern, (match, subTable, subAlias, whereCondition) => {
// 提取主查询的FROM子句
const fromMatch = sql.match(/FROM\s+(\w+)(?:\s+(\w+))?/i);
if (!fromMatch) return match;
const mainTable = fromMatch[1];
const mainAlias = fromMatch[2] || mainTable;
const subTableAlias = subAlias || subTable;
// 构建JOIN条件
const joinCondition = whereCondition.replace(
new RegExp(`\\b${mainAlias}\\.`, 'g'),
`${mainAlias}.`
);
// 替换EXISTS为JOIN
const joinClause = `INNER JOIN ${subTable} ${subTableAlias} ON ${joinCondition}`;
// 在FROM子句后添加JOIN
const newSQL = sql.replace(
/FROM\s+\w+(?:\s+\w+)?/i,
`$& ${joinClause}`
).replace(existsPattern, '');
return newSQL;
});
}
// IN转JOIN
inToJoin(sql) {
// 示例:将IN子查询转换为INNER JOIN
const inPattern = /(\w+)\s+IN\s*\(\s*SELECT\s+(\w+)\s+FROM\s+(\w+)(?:\s+WHERE\s+(.*?))?\s*\)/gi;
return sql.replace(inPattern, (match, column, subColumn, subTable, whereCondition) => {
// 生成唯一的表别名
const subAlias = `sub_${subTable}`;
// 构建JOIN条件
let joinCondition = `${column} = ${subAlias}.${subColumn}`;
if (whereCondition) {
joinCondition += ` AND ${whereCondition.replace(/(\w+)(?=\s*[=<>])/g, `${subAlias}.$1`)}`;
}
// 构建JOIN子句
const joinClause = `INNER JOIN ${subTable} ${subAlias} ON ${joinCondition}`;
// 在FROM子句后添加JOIN
const newSQL = sql.replace(
/FROM\s+\w+(?:\s+\w+)?/i,
`$& ${joinClause}`
).replace(inPattern, 'TRUE'); // 将IN条件替换为TRUE
return newSQL;
});
}
// 标量子查询转JOIN
scalarSubqueryToJoin(sql) {
// 示例:将标量子查询转换为LEFT JOIN
const scalarPattern = /\(\s*SELECT\s+(.*?)\s+FROM\s+(\w+)(?:\s+(\w+))?\s+WHERE\s+(.*?)\s*\)/gi;
return sql.replace(scalarPattern, (match, selectExpr, subTable, subAlias, whereCondition) => {
const subTableAlias = subAlias || `sub_${subTable}`;
// 构建JOIN条件
const joinCondition = whereCondition.replace(/(\w+)(?=\s*[=<>])/g, `${subTableAlias}.$1`);
// 构建JOIN子句
const joinClause = `LEFT JOIN ${subTable} ${subTableAlias} ON ${joinCondition}`;
// 在FROM子句后添加JOIN
const newSQL = sql.replace(
/FROM\s+\w+(?:\s+\w+)?/i,
`$& ${joinClause}`
).replace(scalarPattern, `${subTableAlias}.${selectExpr}`);
return newSQL;
});
}
}
2. JOIN优化
javascript
// JOIN优化重写器
class JoinOptimizer {
constructor() {
this.optimizationRules = [
{
name: 'implicit_to_explicit_join',
pattern: /FROM\s+.*?,.*?\s+WHERE/gi,
optimizer: this.implicitToExplicitJoin.bind(this)
},
{
name: 'join_order_optimization',
pattern: /FROM\s+.*?JOIN.*?JOIN/gi,
optimizer: this.optimizeJoinOrder.bind(this)
},
{
name: 'unnecessary_join_elimination',
pattern: /JOIN.*?ON.*?=/gi,
optimizer: this.eliminateUnnecessaryJoins.bind(this)
}
];
}
// 优化JOIN查询
optimizeJoins(sql, tableStats) {
let optimizedSQL = sql;
const appliedOptimizations = [];
for (const rule of this.optimizationRules) {
if (rule.pattern.test(optimizedSQL)) {
const newSQL = rule.optimizer(optimizedSQL, tableStats);
if (newSQL && newSQL !== optimizedSQL) {
optimizedSQL = newSQL;
appliedOptimizations.push(rule.name);
}
}
}
return {
originalSQL: sql,
optimizedSQL: optimizedSQL,
appliedOptimizations: appliedOptimizations,
improved: appliedOptimizations.length > 0
};
}
// 隐式JOIN转显式JOIN
implicitToExplicitJoin(sql, tableStats) {
// 将逗号分隔的表转换为显式JOIN
const fromMatch = sql.match(/FROM\s+(.*?)\s+WHERE\s+(.*?)(?:\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|$)/i);
if (!fromMatch) return sql;
const fromClause = fromMatch[1];
const whereClause = fromMatch[2];
// 检查是否是隐式JOIN
if (!fromClause.includes(',')) return sql;
const tables = fromClause.split(',').map(t => t.trim());
if (tables.length < 2) return sql;
// 提取JOIN条件
const joinConditions = this.extractJoinConditions(whereClause, tables);
// 构建显式JOIN
let joinSQL = tables[0];
for (let i = 1; i < tables.length; i++) {
const table = tables[i];
const condition = joinConditions.find(c => c.includes(table));
if (condition) {
joinSQL += ` INNER JOIN ${table} ON ${condition}`;
} else {
joinSQL += ` CROSS JOIN ${table}`;
}
}
// 移除WHERE子句中的JOIN条件
let newWhereClause = whereClause;
joinConditions.forEach(condition => {
newWhereClause = newWhereClause.replace(new RegExp(`\\s*AND\\s*${condition}`, 'gi'), '');
newWhereClause = newWhereClause.replace(new RegExp(`^${condition}\\s*AND\\s*`, 'gi'), '');
newWhereClause = newWhereClause.replace(new RegExp(`^${condition}$`, 'gi'), '');
});
// 重构SQL
return sql.replace(
/FROM\s+.*?\s+WHERE\s+.*?(?=\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|$)/i,
`FROM ${joinSQL}${newWhereClause.trim() ? ` WHERE ${newWhereClause}` : ''}`
);
}
// 提取JOIN条件
extractJoinConditions(whereClause, tables) {
const conditions = [];
const tableAliases = tables.map(t => {
const parts = t.split(/\s+/);
return parts.length > 1 ? parts[1] : parts[0];
});
// 查找表之间的等值连接条件
const equalityPattern = /(\w+\.\w+)\s*=\s*(\w+\.\w+)/gi;
let match;
while ((match = equalityPattern.exec(whereClause)) !== null) {
const leftTable = match[1].split('.')[0];
const rightTable = match[2].split('.')[0];
// 检查是否是表之间的连接
if (tableAliases.includes(leftTable) && tableAliases.includes(rightTable)) {
conditions.push(`${match[1]} = ${match[2]}`);
}
}
return conditions;
}
// 优化JOIN顺序
optimizeJoinOrder(sql, tableStats) {
if (!tableStats) return sql;
// 提取JOIN信息
const joinInfo = this.parseJoinStructure(sql);
if (joinInfo.length < 2) return sql;
// 基于表大小重新排序JOIN
const optimizedOrder = this.calculateOptimalJoinOrder(joinInfo, tableStats);
// 重构SQL
return this.reconstructJoinSQL(sql, optimizedOrder);
}
// 解析JOIN结构
parseJoinStructure(sql) {
const joins = [];
const joinPattern = /(LEFT|RIGHT|INNER|CROSS)?\s*JOIN\s+(\w+)(?:\s+(\w+))?\s+ON\s+(.*?)(?=\s+(?:LEFT|RIGHT|INNER|CROSS)?\s*JOIN|\s+WHERE|\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|$)/gi;
let match;
while ((match = joinPattern.exec(sql)) !== null) {
joins.push({
type: match[1] || 'INNER',
table: match[2],
alias: match[3] || match[2],
condition: match[4]
});
}
return joins;
}
// 计算最优JOIN顺序
calculateOptimalJoinOrder(joins, tableStats) {
// 简单策略:小表在前,大表在后
return joins.sort((a, b) => {
const sizeA = tableStats[a.table]?.rowCount || 0;
const sizeB = tableStats[b.table]?.rowCount || 0;
return sizeA - sizeB;
});
}
// 重构JOIN SQL
reconstructJoinSQL(sql, optimizedJoins) {
// 这里需要更复杂的SQL重构逻辑
// 简化实现,实际应该使用SQL解析器
return sql; // 暂时返回原SQL
}
// 消除不必要的JOIN
eliminateUnnecessaryJoins(sql, tableStats) {
// 检查是否有只用于过滤但不返回数据的JOIN
const selectColumns = this.extractSelectColumns(sql);
const joinTables = this.extractJoinTables(sql);
// 找出SELECT中未使用的JOIN表
const unusedJoins = joinTables.filter(table =>
!selectColumns.some(col => col.startsWith(table))
);
if (unusedJoins.length === 0) return sql;
// 将未使用的JOIN转换为EXISTS条件
let optimizedSQL = sql;
unusedJoins.forEach(table => {
optimizedSQL = this.convertJoinToExists(optimizedSQL, table);
});
return optimizedSQL;
}
// 提取SELECT列
extractSelectColumns(sql) {
const selectMatch = sql.match(/SELECT\s+(.*?)\s+FROM/i);
if (!selectMatch || selectMatch[1].includes('*')) return [];
return selectMatch[1].split(',').map(col => col.trim());
}
// 提取JOIN表
extractJoinTables(sql) {
const tables = [];
const joinPattern = /JOIN\s+(\w+)(?:\s+(\w+))?/gi;
let match;
while ((match = joinPattern.exec(sql)) !== null) {
tables.push(match[2] || match[1]);
}
return tables;
}
// 将JOIN转换为EXISTS
convertJoinToExists(sql, table) {
// 简化实现
return sql;
}
}
3. 条件优化
javascript
// 条件优化重写器
class ConditionOptimizer {
constructor() {
this.optimizationRules = [
{
name: 'constant_folding',
optimizer: this.constantFolding.bind(this)
},
{
name: 'predicate_pushdown',
optimizer: this.predicatePushdown.bind(this)
},
{
name: 'redundant_condition_elimination',
optimizer: this.eliminateRedundantConditions.bind(this)
},
{
name: 'range_optimization',
optimizer: this.optimizeRangeConditions.bind(this)
}
];
}
// 优化WHERE条件
optimizeConditions(sql) {
let optimizedSQL = sql;
const appliedOptimizations = [];
for (const rule of this.optimizationRules) {
const newSQL = rule.optimizer(optimizedSQL);
if (newSQL && newSQL !== optimizedSQL) {
optimizedSQL = newSQL;
appliedOptimizations.push(rule.name);
}
}
return {
originalSQL: sql,
optimizedSQL: optimizedSQL,
appliedOptimizations: appliedOptimizations,
improved: appliedOptimizations.length > 0
};
}
// 常量折叠
constantFolding(sql) {
// 计算常量表达式
let optimizedSQL = sql;
// 数学运算
optimizedSQL = optimizedSQL.replace(/(\d+)\s*\+\s*(\d+)/g, (match, a, b) => {
return (parseInt(a) + parseInt(b)).toString();
});
optimizedSQL = optimizedSQL.replace(/(\d+)\s*\-\s*(\d+)/g, (match, a, b) => {
return (parseInt(a) - parseInt(b)).toString();
});
optimizedSQL = optimizedSQL.replace(/(\d+)\s*\*\s*(\d+)/g, (match, a, b) => {
return (parseInt(a) * parseInt(b)).toString();
});
// 布尔运算
optimizedSQL = optimizedSQL.replace(/TRUE\s+AND\s+/gi, '');
optimizedSQL = optimizedSQL.replace(/\s+AND\s+TRUE/gi, '');
optimizedSQL = optimizedSQL.replace(/FALSE\s+OR\s+/gi, '');
optimizedSQL = optimizedSQL.replace(/\s+OR\s+FALSE/gi, '');
return optimizedSQL;
}
// 谓词下推
predicatePushdown(sql) {
// 将WHERE条件尽可能推到子查询中
const subqueryPattern = /\(\s*SELECT.*?FROM\s+(\w+).*?\)/gi;
return sql.replace(subqueryPattern, (subquery) => {
// 提取主查询的WHERE条件
const mainWhereMatch = sql.match(/WHERE\s+(.*?)(?:\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|$)/i);
if (!mainWhereMatch) return subquery;
const mainConditions = this.parseConditions(mainWhereMatch[1]);
// 找出可以下推的条件
const pushdownConditions = mainConditions.filter(condition => {
return this.canPushdown(condition, subquery);
});
if (pushdownConditions.length === 0) return subquery;
// 将条件添加到子查询
const existingWhere = subquery.match(/WHERE\s+(.*?)\)/i);
if (existingWhere) {
const newCondition = existingWhere[1] + ' AND ' + pushdownConditions.join(' AND ');
return subquery.replace(/WHERE\s+.*?\)/, `WHERE ${newCondition})`);
} else {
const insertPos = subquery.lastIndexOf(')');
return subquery.slice(0, insertPos) + ` WHERE ${pushdownConditions.join(' AND ')}` + subquery.slice(insertPos);
}
});
}
// 解析条件
parseConditions(whereClause) {
// 简化实现:按AND分割
return whereClause.split(/\s+AND\s+/i).map(c => c.trim());
}
// 检查是否可以下推
canPushdown(condition, subquery) {
// 检查条件中的列是否在子查询中存在
const columnMatch = condition.match(/(\w+)\s*[=<>!]/);
if (!columnMatch) return false;
const column = columnMatch[1];
return subquery.includes(column);
}
// 消除冗余条件
eliminateRedundantConditions(sql) {
const whereMatch = sql.match(/WHERE\s+(.*?)(?:\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|$)/i);
if (!whereMatch) return sql;
const conditions = this.parseConditions(whereMatch[1]);
const uniqueConditions = [...new Set(conditions)];
if (uniqueConditions.length < conditions.length) {
const newWhereClause = uniqueConditions.join(' AND ');
return sql.replace(/WHERE\s+.*?(?=\s+GROUP\s+BY|\s+ORDER\s+BY|\s+LIMIT|$)/i, `WHERE ${newWhereClause}`);
}
return sql;
}
// 优化范围条件
optimizeRangeConditions(sql) {
// 将多个范围条件合并为BETWEEN
let optimizedSQL = sql;
// 查找 column >= value1 AND column <= value2 模式
const rangePattern = /(\w+)\s*>=\s*(\d+)\s+AND\s+\1\s*<=\s*(\d+)/gi;
optimizedSQL = optimizedSQL.replace(rangePattern, (match, column, min, max) => {
return `${column} BETWEEN ${min} AND ${max}`;
});
// 查找 column > value1 AND column < value2 模式
const exclusiveRangePattern = /(\w+)\s*>\s*(\d+)\s+AND\s+\1\s*<\s*(\d+)/gi;
optimizedSQL = optimizedSQL.replace(exclusiveRangePattern, (match, column, min, max) => {
const minVal = parseInt(min) + 1;
const maxVal = parseInt(max) - 1;
return `${column} BETWEEN ${minVal} AND ${maxVal}`;
});
return optimizedSQL;
}
}
查询重写引擎
1. 统一重写引擎
javascript
// 查询重写引擎
class QueryRewriteEngine {
constructor(pool) {
this.pool = pool;
this.subqueryRewriter = new SubqueryRewriter();
this.joinOptimizer = new JoinOptimizer();
this.conditionOptimizer = new ConditionOptimizer();
this.rewriteHistory = new Map();
this.performanceGains = new Map();
}
// 重写查询
async rewriteQuery(sql, params, options = {}) {
const startTime = Date.now();
try {
// 获取表统计信息
const tableStats = await this.getTableStats(sql);
// 应用重写规则
let currentSQL = sql;
const rewriteSteps = [];
// 1. 子查询优化
if (options.optimizeSubqueries !== false) {
const subqueryResult = this.subqueryRewriter.rewriteQuery(currentSQL);
if (subqueryResult.improved) {
currentSQL = subqueryResult.rewrittenSQL;
rewriteSteps.push({
step: 'subquery_optimization',
appliedRules: subqueryResult.appliedRules,
before: subqueryResult.originalSQL,
after: subqueryResult.rewrittenSQL
});
}
}
// 2. JOIN优化
if (options.optimizeJoins !== false) {
const joinResult = this.joinOptimizer.optimizeJoins(currentSQL, tableStats);
if (joinResult.improved) {
currentSQL = joinResult.optimizedSQL;
rewriteSteps.push({
step: 'join_optimization',
appliedOptimizations: joinResult.appliedOptimizations,
before: joinResult.originalSQL,
after: joinResult.optimizedSQL
});
}
}
// 3. 条件优化
if (options.optimizeConditions !== false) {
const conditionResult = this.conditionOptimizer.optimizeConditions(currentSQL);
if (conditionResult.improved) {
currentSQL = conditionResult.optimizedSQL;
rewriteSteps.push({
step: 'condition_optimization',
appliedOptimizations: conditionResult.appliedOptimizations,
before: conditionResult.originalSQL,
after: conditionResult.optimizedSQL
});
}
}
// 验证重写结果
const isValid = await this.validateRewrite(sql, currentSQL, params);
if (!isValid) {
console.warn('查询重写验证失败,使用原查询');
currentSQL = sql;
rewriteSteps.length = 0;
}
const rewriteTime = Date.now() - startTime;
// 记录重写历史
const rewriteId = this.generateRewriteId(sql);
this.rewriteHistory.set(rewriteId, {
originalSQL: sql,
rewrittenSQL: currentSQL,
rewriteSteps: rewriteSteps,
rewriteTime: rewriteTime,
timestamp: new Date()
});
return {
rewriteId: rewriteId,
originalSQL: sql,
rewrittenSQL: currentSQL,
improved: rewriteSteps.length > 0,
rewriteSteps: rewriteSteps,
rewriteTime: rewriteTime
};
} catch (error) {
console.error('查询重写失败:', error);
return {
originalSQL: sql,
rewrittenSQL: sql,
improved: false,
error: error.message
};
}
}
// 获取表统计信息
async getTableStats(sql) {
const tables = this.extractTableNames(sql);
const stats = {};
for (const table of tables) {
try {
stats[table] = await this.getTableStatistics(table);
} catch (error) {
console.warn(`获取表 ${table} 统计信息失败:`, error.message);
}
}
return stats;
}
// 提取表名
extractTableNames(sql) {
const tables = new Set();
// 提取FROM子句中的表
const fromMatches = sql.match(/FROM\s+(\w+)(?:\s+\w+)?/gi);
if (fromMatches) {
fromMatches.forEach(match => {
const tableName = match.replace(/FROM\s+/i, '').split(/\s+/)[0];
tables.add(tableName);
});
}
// 提取JOIN子句中的表
const joinMatches = sql.match(/JOIN\s+(\w+)(?:\s+\w+)?/gi);
if (joinMatches) {
joinMatches.forEach(match => {
const tableName = match.replace(/JOIN\s+/i, '').split(/\s+/)[0];
tables.add(tableName);
});
}
return Array.from(tables);
}
// 获取表统计信息
async getTableStatistics(tableName) {
const connection = await this.pool.getConnection();
try {
// 获取表行数
const [countResult] = await connection.execute(
`SELECT COUNT(*) as row_count FROM ${tableName}`
);
// 获取表大小
const [sizeResult] = await connection.execute(`
SELECT
ROUND(((data_length + index_length) / 1024 / 1024), 2) as size_mb
FROM information_schema.tables
WHERE table_name = ? AND table_schema = DATABASE()
`, [tableName]);
return {
rowCount: countResult[0].row_count,
sizeMB: sizeResult[0]?.size_mb || 0
};
} finally {
connection.release();
}
}
// 验证重写结果
async validateRewrite(originalSQL, rewrittenSQL, params) {
if (originalSQL === rewrittenSQL) {
return true; // 没有重写,无需验证
}
try {
const connection = await this.pool.getConnection();
// 执行EXPLAIN检查语法
await connection.execute(`EXPLAIN ${rewrittenSQL}`, params);
connection.release();
return true;
} catch (error) {
console.error('重写查询验证失败:', error);
return false;
}
}
// 生成重写ID
generateRewriteId(sql) {
const hash = require('crypto').createHash('md5').update(sql).digest('hex');
return `rewrite_${hash.substring(0, 8)}_${Date.now()}`;
}
// 测试性能改进
async testPerformanceImprovement(rewriteId) {
const rewrite = this.rewriteHistory.get(rewriteId);
if (!rewrite) {
throw new Error('重写记录不存在');
}
const testResults = {
rewriteId: rewriteId,
originalPerformance: null,
rewrittenPerformance: null,
improvement: 0,
recommendUse: false
};
try {
// 测试原查询性能
testResults.originalPerformance = await this.measureQueryPerformance(
rewrite.originalSQL, []
);
// 测试重写查询性能
testResults.rewrittenPerformance = await this.measureQueryPerformance(
rewrite.rewrittenSQL, []
);
// 计算改进
if (testResults.originalPerformance.executionTime > 0) {
const timeSaved = testResults.originalPerformance.executionTime -
testResults.rewrittenPerformance.executionTime;
testResults.improvement = (timeSaved / testResults.originalPerformance.executionTime) * 100;
testResults.recommendUse = testResults.improvement > 10; // 改进超过10%才推荐
}
// 记录性能收益
this.performanceGains.set(rewriteId, testResults);
} catch (error) {
console.error('性能测试失败:', error);
testResults.error = error.message;
}
return testResults;
}
// 测量查询性能
async measureQueryPerformance(sql, params) {
const connection = await this.pool.getConnection();
const startTime = process.hrtime.bigint();
try {
const result = await connection.execute(sql, params);
const endTime = process.hrtime.bigint();
const executionTime = Number(endTime - startTime) / 1000000; // 转换为毫秒
return {
executionTime: executionTime,
rowCount: Array.isArray(result[0]) ? result[0].length : 0,
success: true
};
} catch (error) {
const endTime = process.hrtime.bigint();
const executionTime = Number(endTime - startTime) / 1000000;
return {
executionTime: executionTime,
rowCount: 0,
success: false,
error: error.message
};
} finally {
connection.release();
}
}
// 获取重写统计
getRewriteStats() {
const totalRewrites = this.rewriteHistory.size;
const successfulRewrites = Array.from(this.rewriteHistory.values())
.filter(r => r.rewriteSteps.length > 0).length;
const performanceTests = Array.from(this.performanceGains.values());
const beneficialRewrites = performanceTests.filter(t => t.improvement > 10).length;
const avgImprovement = performanceTests.length > 0 ?
performanceTests.reduce((sum, t) => sum + t.improvement, 0) / performanceTests.length : 0;
return {
totalRewrites: totalRewrites,
successfulRewrites: successfulRewrites,
beneficialRewrites: beneficialRewrites,
successRate: totalRewrites > 0 ? (successfulRewrites / totalRewrites) * 100 : 0,
averageImprovement: avgImprovement,
recentRewrites: Array.from(this.rewriteHistory.values())
.sort((a, b) => b.timestamp - a.timestamp)
.slice(0, 10)
};
}
}
总结
查询重写是数据库性能优化的高级技术:
- 子查询优化:将子查询转换为JOIN提升性能
- JOIN优化:优化JOIN顺序和类型
- 条件优化:简化和优化WHERE条件
- 自动化重写:建立自动化的查询重写流程
- 性能验证:验证重写效果和性能改进
- 持续优化:基于统计信息持续优化重写规则
通过系统化的查询重写,可以在不修改应用代码的情况下显著提升查询性能。