-
Notifications
You must be signed in to change notification settings - Fork 924
perf: cache prepared statements across .prepareStatement calls #319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| /*------------------------------------------------------------------------- | ||
| * | ||
| * Copyright (c) 2015, PostgreSQL Global Development Group | ||
| * | ||
| * | ||
| *------------------------------------------------------------------------- | ||
| */ | ||
| package org.postgresql.core; | ||
|
|
||
| import org.postgresql.util.CanEstimateSize; | ||
|
|
||
| /** | ||
| * Stores information on the parsed JDBC query. | ||
| * It is used to cut parsing overhead when executing the same query through {@link java.sql.Connection#prepareStatement(String)}. | ||
| */ | ||
| public class CachedQuery implements CanEstimateSize { | ||
| /** | ||
| * Cache key. {@link String} or {@link org.postgresql.jdbc2.CallableQueryKey} | ||
| */ | ||
| public final Object key; | ||
| public final Query query; | ||
| public final boolean isFunction; | ||
| public final boolean outParmBeforeFunc; | ||
|
|
||
| private int executeCount; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This class is shared between threads. This should probably be an
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| public CachedQuery(Object key, Query query, boolean isFunction, boolean outParmBeforeFunc) | ||
| { | ||
| this.key = key; | ||
| this.query = query; | ||
| this.isFunction = isFunction; | ||
| this.outParmBeforeFunc = outParmBeforeFunc; | ||
| } | ||
|
|
||
| public void increaseExecuteCount() { | ||
| if (executeCount < Integer.MAX_VALUE) | ||
| executeCount++; | ||
| } | ||
|
|
||
| public void increaseExecuteCount(int inc) { | ||
| int newValue = executeCount + inc; | ||
| if (newValue > 0) // if overflows, just ignore the update | ||
| executeCount = newValue; | ||
| } | ||
|
|
||
| /** | ||
| * Number of times this statement has been used | ||
| * @return number of times this statement has been used | ||
| */ | ||
| public int getExecuteCount() { | ||
| return executeCount; | ||
| } | ||
|
|
||
| @Override | ||
| public long getSize() | ||
| { | ||
| int queryLength = String.valueOf(key).length() * 2 /* 2 bytes per char */; | ||
| return queryLength * 2 /* original query and native sql */ + 100 /* entry in hash map, CachedQuery wrapper, etc */; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| /*------------------------------------------------------------------------- | ||
| * | ||
| * Copyright (c) 2003-2014, PostgreSQL Global Development Group | ||
| * Copyright (c) 2004, Open Cloud Limited. | ||
| * | ||
| * | ||
| *------------------------------------------------------------------------- | ||
| */ | ||
| package org.postgresql.core; | ||
|
|
||
| /** | ||
| * Represents a query that is ready for execution by backend. | ||
| * The main difference from JDBC is ? are replaced with $1, $2, etc. | ||
| */ | ||
| public class NativeQuery { | ||
| private final static String[] BIND_NAMES = new String[128]; | ||
| private final static int[] NO_BINDS = new int[0]; | ||
|
|
||
| public final String nativeSql; | ||
| public final int[] bindPositions; | ||
|
|
||
| static | ||
| { | ||
| for (int i = 1; i < BIND_NAMES.length; i++) | ||
| { | ||
| BIND_NAMES[i] = "$" + i; | ||
| } | ||
| } | ||
|
|
||
| public NativeQuery(String nativeSql) | ||
| { | ||
| this(nativeSql, NO_BINDS); | ||
| } | ||
|
|
||
| public NativeQuery(String nativeSql, int[] bindPositions) | ||
| { | ||
| this.nativeSql = nativeSql; | ||
| this.bindPositions = bindPositions == null || bindPositions.length == 0 ? NO_BINDS : bindPositions; | ||
| } | ||
|
|
||
| /** | ||
| * Stringize this query to a human-readable form, substituting | ||
| * particular parameter values for parameter placeholders. | ||
| * | ||
| * @param parameters a ParameterList returned by this Query's | ||
| * {@link Query#createParameterList} method, or <code>null</code> to | ||
| * leave the parameter placeholders unsubstituted. | ||
| * @return a human-readable representation of this query | ||
| */ | ||
| public String toString(ParameterList parameters) | ||
| { | ||
| if (bindPositions.length == 0) | ||
| return nativeSql; | ||
|
|
||
| StringBuilder sbuf = new StringBuilder(nativeSql.length()); | ||
| sbuf.append(nativeSql, 0, bindPositions[0]); | ||
| for (int i = 1; i <= bindPositions.length; ++i) | ||
| { | ||
| if (parameters == null) | ||
| sbuf.append('?'); | ||
| else | ||
| sbuf.append(parameters.toString(i)); | ||
| int nextBind = i < bindPositions.length ? bindPositions[i] : nativeSql.length(); | ||
| sbuf.append(nativeSql, bindPositions[i - 1] + bindName(i).length(), nextBind); | ||
| } | ||
| return sbuf.toString(); | ||
| } | ||
|
|
||
| /** | ||
| * Returns $1, $2, etc names of bind variables used by backend. | ||
| * @param index index of a bind variable | ||
| * @return bind variable name | ||
| */ | ||
| public static String bindName(int index) { | ||
| return index < BIND_NAMES.length ? BIND_NAMES[index] : "$" + index; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you mean mega bytes ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure he does mean mebibytes. It explicitly means 2^20 vs 10^6.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to use this ? Seems a bit esoteric ?
Dave Cramer
On 28 June 2015 at 11:20, Sehrope Sarkuni [email protected] wrote:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well technically it's the correct term for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dave Cramer
On 28 June 2015 at 12:02, Sehrope Sarkuni [email protected] wrote:
Yes, but not very well known.