Last active
August 29, 2015 14:23
-
-
Save seratch/62b6f99c8b4e970898fb to your computer and use it in GitHub Desktop.
PostgreSQLAnalyzer for ScalikeJDBC Users
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package lib | |
| import java.sql.Timestamp | |
| import org.joda.time._ | |
| import scalikejdbc._ | |
| /** | |
| * Usage: | |
| * scalikekdbc.GlobalSettings.queryCompletionListener = PostgreSQLAnalyzer.queryCompletionListener | |
| */ | |
| object PostgreSQLAnalyzer { | |
| private val highestCostRegexp = "\\(cost=[\\d\\.]+\\.\\.([\\d\\.]+)".r | |
| lazy val queryCompletionListener: (String, Seq[Any], Long) => Unit = { | |
| (statement: String, params: Seq[Any], millis: Long) => | |
| { | |
| DB.readOnly { session => | |
| val stmt = session.connection.createStatement() | |
| val query = sql"explain ${SQLSyntax.createUnsafely(statement, params)}" | |
| val explainQuery = query.parameters.foldLeft(query.statement) { | |
| case (query, param) => | |
| val value = param match { | |
| case None => "null" | |
| case Some(str: String) => s"'${str}'" | |
| case Some(v) => v.toString | |
| case str: String => s"'${str}'" | |
| case datetime: DateTime => s"'${datetime.toString}'" | |
| case timestamp: Timestamp => s"'${timestamp.toString}'" | |
| case v => v.toString | |
| } | |
| query.replaceFirst("\\?", value) | |
| } | |
| var isLowCostQuery = false | |
| val lines: Traversable[String] = new ResultSetTraversable(stmt.executeQuery(explainQuery)).flatMap { rs => | |
| if (!isLowCostQuery) { | |
| val line = rs.string(1) | |
| highestCostRegexp.findAllIn(line).matchData.toSeq.headOption.map(_.group(1)) match { | |
| case Some(cost) if cost.toDouble < 1000 => | |
| isLowCostQuery = true | |
| None | |
| case _ => | |
| Some(" " + line) | |
| } | |
| } else { | |
| None | |
| } | |
| } | |
| if (lines.size > 0) { | |
| println(lines.mkString("\n")) | |
| println | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment