Opened 4 years ago

Closed 4 years ago

#9007 closed defect (bug) (fixed)

Poor get_category_children() performance; rewrite to use get_term_children()

Reported by: _timk Owned by: ryan
Priority: normal Milestone: 2.8
Component: Taxonomy Version: 2.7
Severity: normal Keywords: has-patch get_category_children
Cc:

Description

I'm working on a WordPress site with a few thousand categories. The categories are structured a bit, with one master category, a few organizational subcategories, and then the bulk of the remaining categories under those.

I'm looking to get a list of children for one of the middle-tier categories. Running get_categories() with the 'child_of' parameter calls get_category_children(). This call hits the 30-second server time limit. Outside the web environment, get_category_children() takes around a minute and 40 seconds to build a list of 589 categories on a relatively powerful desktop PC.

I'll attach a revised, non-recursive implementation of get_category_children() that uses get_term_children() and runs several orders of magnitude faster than the original in my environment. It returns almost instantly.

Attachments (2)

category-template.diff (1.2 KB) - added by _timk 4 years ago.
Patch: rewritten get_category_children() using get_term_children()
deprecate_get_category_children.9007.diff (2.5 KB) - added by filosofo 4 years ago.
Deprecate get_category_children. Really, how often do you need a string of concatenated category children ids?

Download all attachments as: .zip

Change History (10)

_timk4 years ago

Patch: rewritten get_category_children() using get_term_children()

I re-ran the tests and came up with rough (time- and microtime-measured) execution times of 87 seconds and 0.00099 seconds for the original and revised implementations, respectively.

Improvement of almost 5 orders of magnitude for my case, extracting just under 600 child categories from a total of 1500+ in the database.

  • Component changed from General to Template

comment:3   DD324 years ago

  • Component changed from Template to Taxonomy
  • Owner changed from anonymous to ryan
  • Keywords has-patch get_category_children added

_timk, thanks for bringing this old function to light, but there are some odd things here.

  • You say that your problems stemmed from get_categories's calling get_category_children, but get_categories has never used get_category_children. Up to version 2.3 of WordPress, get_categories did use the private function _get_cat_children, but that was dropped in 2.3 with the implementation of the new taxonomy system.
  • Since WordPress 2.3 no core functions have called get_category_children. It's basically a vestige from the 2.2 and earlier days when it was used to build category queries.
  • get_category_children, having been used originally in core to build category queries, would have been better off as a private function, IMO.
  • get_category_children is not used in core, and my grep of the plugins repository turns up its use in only 5 plugins. Of those plugins, 3 seem to have been abandoned, as they're using the old 2.2 category tables. The other 2 say "tested up to 2.5.1"
  • So I think we should deprecate get_category_children. My patch does that.
  • _timk, if you're having performance issues in WordPress 2.7 or trunk, it's probably due to something else---let's try to figure out what that is.

Deprecate get_category_children. Really, how often do you need a string of concatenated category children ids?

You're right, of course; my apologies. I somehow managed to misread both the xdebug call trace and a quick grep through the tree to make sure the function wasn't an orphan. It turns out the function was being called directly on a portion of the site under someone else's control.

I support deprecation. When I first encountered the function, I actually expected it to behave like get_term_children(), returning an array of category IDs or objects.

Just discovered that get_category_children() was used because it's in an example in the documentation for in_category().

I changed the wiki example you linked to to use get_term_children

comment:8   ryan4 years ago

  • Resolution set to fixed
  • Status changed from new to closed

(In [10703]) Deprecate get_category_children(). Props filosofo. fixes #9007

Note: See TracTickets for help on using tickets.