Skip to content
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

CRM-20455 - DB_common::modifyQuery() - Optimize #259

Merged
merged 1 commit into from
Jul 26, 2019

Conversation

totten
Copy link
Member

@totten totten commented Jul 25, 2019

Overview

The recently merged PR #180 added modifyQuery() to allow dynamic inspection/modification of most SQL queries (post-boot).

This patch modifies and micro-optimizes the new (unreleased) interface.

Ordinarily, one wouldn't care about this level of micro-optimization; however, it's entirely foreseeable that this code will run hundreds or even thousands of times while a user works with a single page.

Depends: civicrm/civicrm-core#14882, civicrm/civicrm-core#14883

Before

For each typical SQL query, the call to modifyQuery() requires:

  • Constructing an instance of GenericHookEvent, which does some array shuffling and encourages reflective code.
  • Performing multiple lookups of the container/dispatcher system

After

For each typical SQL query, the call to modifyQuery() requires:

  • Constructing an instance of QueryEvent, which is a lighter object
  • Fewer lookups (isset(Civi::$static[...]))

Comments

I did some simple benchmarks -- running 10,000 simple SQL queries with various forms of modifyQuery(). The baseline (no events) had the fastest average (9.444s). Adding GHE bumped runtime up +9% (10.298s). With this patch, it only adds +3.5% (9.787s).

The averages are based on 5 samples each. For full details, see https://gist.github.com/totten/da21a8386a7ddcc62def5d78e912bf8c

Overview
--------

The recently merged PR civicrm#180 added `modifyQuery()` to allow dynamic
inspection/modification of most SQL queries (*post-boot*).

This patch modifies and micro-optimizes the new (unreleased) interface.

Ordinarily, one wouldn't care about this level of micro-optimization;
however, it's entirely foreseeable that this code will run hundreds or even
thousands of times while a user works with a single page.

Before
------

For each typical SQL query, the call to `modifyQuery()` requires:

* Constructing an instance of `GenericHookEvent`, which does some
  array shuffling and encourages reflective code.
* Performing multiple lookups of the container/dispatcher system

After
-----

For each typical SQL query, the call to `modifyQuery()` requires:

* Constructing an instance of `QueryEvent`, which is a lighter object
* Fewer lookups (`isset(Civi::$static[...])`)

Comments
--------

I did some simple benchmarks -- running 10,000 simple SQL queries with
various forms of `modifyQuery()`.  The baseline (no events) had the fastest
average (`9.444`s).  Adding GHE bumped runtime up +9% (`10.298`s).  With
this patch, it only adds +3.5% (`9.787`s).

The averages are based on 5 samples each.  For full details, see
https://gist.github.com/totten/da21a8386a7ddcc62def5d78e912bf8c
@civibot
Copy link

civibot bot commented Jul 25, 2019

(Standard links)

@civibot civibot bot added the master label Jul 25, 2019
@eileenmcnaughton
Copy link
Contributor

thanks @totten 300ms over 10k queries seems OK to me & def better!

@seamuslee001
Copy link
Contributor

Error was

/home/jenkins/bknix-dfl/build/pkg-259-592jo/web/sites/all/modules/civicrm/packages/DB/common.php).
Error: Class 'Civi\Core\Event\QueryEvent' not found in DB_common->modifyQuery() (line 1162 of /home/jenkins/bknix-dfl/build/pkg-259-592jo/web/sites/all/modules/civicrm/packages/DB/common.php).
Drush command terminated abnormally due to an unrecoverable error.       [error]

which makes sense as the core PR hadn't been merged

@seamuslee001
Copy link
Contributor

Jenkins re test this please

@totten
Copy link
Member Author

totten commented Jul 25, 2019

Cool, the second test-run showed that 14882 fixed the QueryEvent error. It also revealed some test-harness issues, which are addressed in another PR: civicrm/civicrm-core#14883 . We'll need another test-run after that's merged.

@eileenmcnaughton
Copy link
Contributor

test this please

@seamuslee001 seamuslee001 merged commit 860d37b into civicrm:master Jul 26, 2019
@totten totten deleted the master-query-event branch July 26, 2019 20:34
@eileenmcnaughton
Copy link
Contributor

Just a note that I'm doing some performance tests before deploying some updates.

My first tests on 5.13 were importing (via script) around 462 contacts with contributions per minute. On 5.17 both with and without using this query modifier I was getting around 484 contributions per minute.

I don't consider the above to be reliable enough to say 5.17 is definitely faster than 5.13 but I think it is reliable enough to say the query modifier is not dragging us down

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants