如何为Oracle方言添加optimizer hint #475
-
Oracle的optimizer hint语法如下: SELECT /*+ LEADING(e2 e1) USE_NL(e1) INDEX(e1 emp_emp_id_pk)
USE_MERGE(j) FULL(j) */
e1.first_name, e1.last_name, j.job_id, sum(e2.salary) total_sal
FROM employees e1, employees e2, job_history j
WHERE e1.employee_id = e2.manager_id
AND e1.employee_id = j.employee_id
AND e1.hire_date = j.start_date
GROUP BY e1.first_name, e1.last_name, j.job_id
ORDER BY total_sal; 需要在 const val OPTIMIZER_HINTS_KEY = "optimizerHints"
class ExtendedOracleFormatter(database: Database, beautifySql: Boolean, indentSize: Int) :
OracleFormatter(database, beautifySql, indentSize) {
// ⚠️注意:ktorm版本更新时,一定要同步更新该方法
override fun visitSelect(expr: SelectExpression): SelectExpression {
val optimizerHints: List<String>? = (expr.extraProperties[OPTIMIZER_HINTS_KEY] as? List<*>)?.mapNotNull { it as? String }
if (optimizerHints.isNullOrEmpty()) {
return super.visitSelect(expr)
}
// 以下为super.visitSelect(expr)代码,在select关键字后插入了optimizer hint
writeKeyword("select ")
// 插入optimizer hint
write("/*+ ${optimizerHints.joinToString(" ")} */ ")
// 插入optimizer hint END
if (expr.isDistinct) {
writeKeyword("distinct ")
}
// 剩余的super.visitSelect(expr)代码,此处省略
...
}
}
fun SelectExpression.withOptimizerHints(hints: List<String>): SelectExpression {
return this.copy(
extraProperties = extraProperties.toMutableMap().apply { put(OPTIMIZER_HINTS_KEY, hints) }
)
}
fun Query.withOptimizerHints(vararg hints: String): Query = withOptimizerHints(hints.toList())
fun Query.withOptimizerHints(hints: List<String>): Query {
return this.withExpression(
when (val expression = this.expression) {
is SelectExpression -> expression.withOptimizerHints(hints)
is UnionExpression -> throw IllegalStateException("Optimizer hints are not supported in a union expression.")
}
)
}
fun <E : Any, T : BaseTable<E>> EntitySequence<E, T>.withOptimizerHints(vararg hints: String): EntitySequence<E, T> = withOptimizerHints(hints.toList())
fun <E : Any, T : BaseTable<E>> EntitySequence<E, T>.withOptimizerHints(hints: List<String>): EntitySequence<E, T> {
return this.withExpression(expression.withOptimizerHints(hints))
} optimizer hint保存在 database.exampleEntities.withOptimizerHints("index(example_table EXAMPLE_IDX1)", "hint2", "hint3")
.filter { it.employee_id eq employee_id }
.toList() 这样写虽然能实现功能,但是重写的 |
Beta Was this translation helpful? Give feedback.
Answered by
vincentlauvlwj
Jan 31, 2023
Replies: 1 comment 3 replies
-
可以考虑写成嵌套查询 const val OPTIMIZER_HINTS_KEY: String = "optimizerHints"
class ExtendedOracleFormatter(
database: Database, beautifySql: Boolean, indentSize: Int
) : OracleFormatter(database, beautifySql, indentSize) {
@Suppress("UNCHECKED_CAST")
override fun visitSelect(expr: SelectExpression): SelectExpression {
val hints = expr.extraProperties[OPTIMIZER_HINTS_KEY] as? List<String>
if (hints.isNullOrEmpty()) {
return super.visitSelect(expr)
}
writeKeyword("select * ")
write("/*+ ${hints.joinToString(" ")} */ ")
newLine(Indentation.SAME)
writeKeyword("from ")
visitQuerySource(expr)
newLine(Indentation.SAME)
return expr
}
} |
Beta Was this translation helpful? Give feedback.
3 replies
Answer selected by
tzhao11
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
可以考虑写成嵌套查询