-
-
Notifications
You must be signed in to change notification settings - Fork 814
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-20199 Contribution search performance #9631
CRM-20199 Contribution search performance #9631
Conversation
eileenmcnaughton
commented
Jan 4, 2017
•
edited by civicrm-builder
Loading
edited by civicrm-builder
- CRM-19830: Cleanup contribution search by making non-exportable fields exportable
- CRM-19815: Remove performance degrading-joins from civicrm_contribution search
- CRM-20199: Contribution searches all include an unindexed join
@colemanw @monishdeb FYI - I am trying to clean up the contribution search class a bit in order to fix some of the performance issues. I dug into why some fields were manually declared in the hope of being a bit more meta-data-ey & found that it was because they were set to export = false. In each case a whole lot of handling had been added to compensate for it so I think we can add export = true more aggressively. I'd like to remove the handling for contribution_check_number but it seems that as a result of it being there contribution_check_number is accepted & output (which is used by search fields & could possibly conflict with trxn_id I guess.....). I think the hated uniquenames are the right answer here + add a bit of handling in the contribution.get api to copy $result['contribution_check_number' to $result['check_number'] - this doesn't happen currently for contribution_source but perhaps it should. That + dealing properly with the pseudoconstant fields (payment_instrument, financial_type, contribution_status is next) Contribution is of course one of a handful of api using the query object.... |
CRM/Contribute/BAO/Query.php
Outdated
@@ -157,100 +151,12 @@ public static function select(&$query) { | |||
$query->_tables['civicrm_contribution'] = 1; | |||
} | |||
|
|||
// LCD 716 | |||
$includeSoftCredits = self::isSoftCreditOptionEnabled($query->_params); |
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.
This is just moved
CRM/Contribute/BAO/Query.php
Outdated
if (!empty($query->_returnProperties['contribution_campaign_title'])) { | ||
$query->_select['contribution_campaign_title'] = "civicrm_campaign.title as contribution_campaign_title"; | ||
$query->_element['contribution_campaign_title'] = $query->_tables['civicrm_campaign'] = 1; | ||
} | ||
|
||
// Adding address_id in a way that is more easily extendable since the above is a bit ... wordy. | ||
$supportedBasicReturnValues = array('address_id'); |
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.
not needed now the field is set to export
CRM/Contribute/BAO/Query.php
Outdated
} | ||
|
||
//CRM-16116: get financial_type_id | ||
if (!empty($query->_returnProperties['financial_type_id'])) { |
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.
not needed now the field is set to export
Jenkin test this please |
c582a7d
to
38af28f
Compare
Phew, I got it to pass. I do think handling oddness is better done near the 'edges' of the app - ie. forms & apis can handle field wierdness & pushing wierdness out from the BAO is generally good |
7a18987
to
bcd9856
Compare
CRM/Contact/BAO/Query.php
Outdated
if ( | ||
(substr($name, 0, 12) == 'participant_') || | ||
(substr($name, 0, 7) == 'pledge_') || | ||
(substr($name, 0, 5) == 'case_') || |
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.
ie do not skip the loop for fields starting with contribution_ as many of them are in fact better dealt with in that context since they can be derived from metadata
CRM/Contact/BAO/Query.php
Outdated
@@ -680,15 +697,12 @@ public function selectClause($apiEntity = NULL) { | |||
} | |||
} | |||
|
|||
if (in_array($name, array('prefix_id', 'suffix_id', 'gender_id', 'communication_style_id'))) { |
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.
Consolidate this logic with general option-value pseudoconstant metadata based evaluation further down
CRM/Contact/BAO/Query.php
Outdated
if ( | ||
!empty($this->_paramLookup[$name]) | ||
|| !empty($this->_returnProperties[$name]) | ||
|| $this->pseudoConstantNameIsInReturnProperties($field) |
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.
$this->pseudoConstantNameIsInReturnProperties replaces the earlier in_array call
CRM/Contact/BAO/Query.php
Outdated
if ($fieldName == 'organization_name') { | ||
$this->_select[$name] = "IF ( contact_a.contact_type = 'Individual', NULL, contact_a.organization_name ) as organization_name"; | ||
} | ||
elseif ($fieldName != 'id') { |
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.
move all this stuff out of the 'contact-table-specific' & make it just 'metadata-based'
CRM/Contact/BAO/Query.php
Outdated
// If we have an option group defined then rather than joining the option value table in | ||
// (which is an unindexed join) we render the option value on output. | ||
// @todo - extend this to other pseudoconstants. | ||
if ($this->pseudoConstantNameIsInReturnProperties($field)) { |
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.
By adding all option-value based fields (that get here) to the pseudoconstant array they become workable in the context of the $convertToPseudoFields fn
CRM/Contact/BAO/Query.php
Outdated
} | ||
else { | ||
$order = " ORDER BY contact_a.sort_name asc, contact_a.id"; | ||
} | ||
} | ||
if (!$order && empty($orderByArray)) { |
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.
Refactoring in this function ensures an array of order-by fields although it is still pretty funky. Previously the function did not iterate through all fields - just the first one in the string, to add special handling.
The handling we are adding is a way of avoiding joining the option_value table in when sorting by it. By rendering the values in php & using field($fieldName, 4,6,7) I was able to render the query without the join. Results in test were 10 times faster, in some cases much more.
CRM/Contribute/BAO/Contribution.php
Outdated
@@ -825,15 +838,6 @@ public static function &exportableFields($checkPermission = TRUE) { | |||
), | |||
); | |||
|
|||
$contributionRecurId = array( |
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.
As part of this PR I declared this field as exportable so it no longer needs manual adding to exportable fields
CRM/Contribute/BAO/Contribution.php
Outdated
$expFieldProduct = CRM_Contribute_DAO_Product::export(); | ||
$expFieldsContrib = CRM_Contribute_DAO_ContributionProduct::export(); | ||
$typeField = CRM_Financial_DAO_FinancialType::export(); | ||
$financialAccount = CRM_Financial_DAO_FinancialAccount::export(); | ||
$optionField = CRM_Core_OptionValue::getFields($mode = 'contribute'); |
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.
as part of this PR I declared payment_instrument_id as exportable so it no longer needs manual adding
$expFieldProduct = CRM_Contribute_DAO_Product::export(); | ||
$expFieldsContrib = CRM_Contribute_DAO_ContributionProduct::export(); | ||
$typeField = CRM_Financial_DAO_FinancialType::export(); | ||
$financialAccount = CRM_Financial_DAO_FinancialAccount::export(); | ||
$optionField = CRM_Core_OptionValue::getFields($mode = 'contribute'); | ||
$contributionStatus = array( |
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.
now handled by the pseudoconstant - not needed as a manual add on
0b8429f
to
74ec330
Compare
ba3db65
to
e880e69
Compare
ef71754
to
3cbea72
Compare
25c03dd
to
4bd03eb
Compare
…ion search. This involves setting payment instrument to exportable & remove hacks that were used in place of doing that, and adding new logic to the order by to allow it to order without joining the option value table (using the field() function). I have observed one small regression which is the Qill showing 'Payment Method ID' instead of payment method. I'm committed to fixing that but I would push to merge this in advance of that because we are in the best place in the monthly cycle to merge this and that is a very minor fallout.
4bd03eb
to
9d5c7f1
Compare
@seamuslee001 this is the remaining work to remove the slow joins. I don't feel I can break it into any smaller chunks & I do think this is a good time of the cycle to merge it. From the commit notes
|
@eileenmcnaughton i have tested this on export and search and all appears fine. I think we can address the Qill issue in another PR |
I did an export of a saved field mapping, There were no signs of fields missing and then on export fields were correctly populated as expected |
:-) |
…arch CRM-20199 Contribution search performance