-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[Performance] Category manager / Tag Manager, get all counters via single query, reduce 20, 50, 100 queries (page limit) to 1 #22117
Conversation
very well done 👍 |
// Get relation counts for all category objects with single query | ||
$query = $db->getQuery(true) | ||
->select('catid, ' . $state_column . ' AS state, count(*) AS count') | ||
->from($db->qn('#__' . $related_tbl)) |
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.
Replace $db->qn
by $db->quoteName
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.
- use $db->quoteName() where needed
the same "optimization" should be done on every "category" banner, contact etc.... |
|
||
// Get relation counts for all category objects with single query | ||
$query = $db->getQuery(true) | ||
->select('catid, ' . $state_column . ' AS state, count(*) AS count') |
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.
Capitalize count(*)
even better can be done on some high level "category" CLASS/HELPER |
dae4586
to
f10fb8b
Compare
yes that was my thought too I intended to replace countItems() method everywhere, but i see that countTagItems() has the same problem of 20, 50, 100 queries instead of 1 so i have added a countRelations() method to parent helper class that replace both methods, |
|
// The relation query does not return a value for cases without relations of a particular state / condition, set zero as default | ||
foreach ($items as $item) | ||
{ | ||
foreach($counter_names as $n) |
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.
Add space before (
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.
Thanks, done this and other CS errors
That PR has a completely different purpose than PR #21667, Furthermore this PR not only replaces multiple queries for category assignments with 1 query (this is the purpose of this PR) A note |
Of course if you would want to do same optimization inside PR |
* | ||
* @return stdClass[] | ||
* | ||
* @since 3.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.
Change to __DEPLOY_VERSION__
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.
thanks, lol, i remember adding DEPLOY_VERSION for 2 methods,
but then the 2 methods became 1 because 80% of their code was the same
please, can I ask you if can we concentrate our effort on 3.x series for a while !! |
sure, just i mention that the configuration object of the method countRelations() is structured having in mind to make easy
|
sorry for my idiosyncrasy... i just want to plant my foots on earth and not on mars |
This function is used only in the back end category list view. As far as I can see it, it is executed only once. But please prove that I'm wrong. |
Sure here is the proof foreach ($items as $item)
{
$item->count_trashed = 0;
$item->count_archived = 0;
$item->count_unpublished = 0;
$item->count_published = 0;
$query = $db->getQuery(true);
$query->select('state, count(*) AS count')
->from($db->qn('#__content'))
->where('catid = ' . (int) $item->id)
->group('state');
$db->setQuery($query);
$articles = $db->loadObjectList();
...
} and then also i tested to confirm that they are executed, and then spent considerable time for this PR also revising code for tags assignments too You can confirm the multiple queries by looking at the Debug queries slider, and then also inside the items loop after: you can add echo 'Executed : ' . $query . '<br><br>'; |
I speak of the multiple sql queries (20, 50, 100) that a single call to the methods will do i never said that the method is called multiple times |
Now I got you. |
What's the idea behind the config variable? |
ggppdk
I didn't noticed that you changed the complete PR to more then changing the DB query sorry I missed this I talked about this part. |
basically it makes possible the method to be reusable also copying this from my previous answer
e.g. banner has different table name and different column name than content also the counting for fields in fieldgroups does not use 'catid' column, the column name is 'group_id' |
I have tested this item ✅ successfully on 0028cc8 This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/22117. |
I have tested this item ✅ successfully on 3d7db8c This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/22117. |
RTC This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/22117. |
@ggppdk Can you explain why you have: public static function countItems(&$items, $config = null)
{
$config = $config ?: (object) array(
'related_tbl' => 'banners',
'state_col' => 'state',
'group_col' => 'catid',
'relation_type' => 'category_or_group',
);
return parent::countRelations($items, $config);
} IMO this would be better: public static function countItems(&$items)
{
$config = (object) array(
'related_tbl' => 'banners',
'state_col' => 'state',
'group_col' => 'catid',
'relation_type' => 'category_or_group',
);
return parent::countRelations($items, $config);
} If someone would like to change some parameter then should use |
indeed if someone would want to count relations with a custom table / custom case, which is the method inherited by the parent class So indeed it seems to me that it can be as you say, public static function countItems(&$items, $config = null)
public static function countTagItems(&$items, $extension, $config = null) they can be (have same signature like before this) public static function countItems(&$items)
public static function countTagItems(&$items) |
Please remove RTC in last CS commit the table aliases are no longer added correctly (i think they are not, i will test) |
Status back on Pending as stated above. This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/22117. |
…nterRelations() method in ContentHelper class
3d7db8c
to
f6591df
Compare
Ok i retested, everything seems corrects, |
I have tested this item ✅ successfully on 3a580e4ba0f8ba273cf85fa63cfeda8ab8c30a8. There is a problem with mark this test as success on github. |
I have tested this item successfully but I got error "Bad credentials" at https://issues.joomla.org/tracker/joomla-cms/22117 |
I have tested this item ✅ successfully on 23a580e This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/22117. |
RTC This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/22117. |
Pull Request for Issue # .
Summary of Changes
Category manager creates 1 query per category to get the assigned item counts by state
These are used to displays the columns
total published, total unpublished, total archived, total trashed
Testing Instructions
Both 1st and 2nd tabs should show the same counted items per state
Category managers to test
Tags manager:
Expected result
1 query to get the total assigned items for the categories shown by current page
Actual result
20, 50, 100 queries to get the assigned items for the categories
Documentation Changes Required
None