Home » Performance » MySQL » Stuck With Bad Category Filter Performance
Stuck With Bad Category Filter Performance [message #3437] Sat, 16 August 2008 08:22 Go to next message
w00t08
Messages: 2
Registered: August 2008
Junior Member
Hey folks,

I'm a little stuck. I got the following tables:
CREATE TABLE `items` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `unlocked` tinyint(1) NOT NULL default '0',
  `name` varchar(200) NOT NULL,
  `meta_cat_type` enum('blah','foo','bar') default NULL,
  `post_time` int(10) unsigned NOT NULL default '0',
  `unlock_time` int(10) unsigned NOT NULL,
  `allow_comments` tinyint(1) NOT NULL default '1',
  `posted_by` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `name` (`name`),
  KEY `post_time` (`post_time`),
  KEY `meta_cat_type` (`meta_cat_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

CREATE TABLE `item_cats` (
  `item_id` int(10) unsigned NOT NULL,
  `cat_id` smallint(5) unsigned NOT NULL,
  KEY `item_id` (`item_id`),
  KEY `cat_id` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

CREATE TABLE `item_filters` (
  `user_id` int(10) unsigned NOT NULL,
  `cat_id` smallint(5) unsigned NOT NULL,
  `meta_cats` set('blah','foo','bar') NOT NULL,
  `filter_type` enum('overview','global') NOT NULL,
  UNIQUE KEY `id` (`user_id`,`cat_id`,`filter_type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


So each item can belong to many categories. Pretty much standard stuff.

Now I have a typical view-items-with-pagination-and-stuff thing set up, so I need to get the total number of items and the items on the current page. My current query to get these looks like this, but it's rather slow as the sub query has to be executed once for every row in the items table (which currently has about 50,000 rows and is growing continuously).

SELECT COUNT( * )
FROM items
WHERE unlocked =1
AND (
  NOT EXISTS (
    SELECT * FROM item_filters f, item_cats c
    WHERE f.user_id = "823"
      AND f.cat_id = c.cat_id
      AND c.item_id = items.id
      AND f.filter_type = "overview"
      AND FIND_IN_SET( items.meta_cat_type, meta_cats )
)


Any help on how to speed this up is greatly appreciated! Thanks in advance. Smile
Re: Stuck With Bad Category Filter Performance [message #3440 is a reply to message #3437 ] Sun, 17 August 2008 10:30 Go to previous messageGo to next message
Speeple  is currently offline Speeple
Messages: 91
Registered: August 2006
Member
Just a quick observation is that you have no primary key for item_cats.

Try creating a PK:

PRIMARY KEY (`item_id`, `cat_id`)

Possible storage reductions:

INT + SMALLINT = 6 bytes

INDEX(`cat_id`) (for tag clouds I assume?): 2 bytes

Total: 6 + 2 = 8

Currently:

6 bytes (InnoDB auto PK) + 4 bytes (INT) + 2 bytes (SMALLINT) = 12 bytes

Lookups on a "clustered" primary key are also more efficient.

Other than that, I don't know how you can really improve the performance of the query without making some design changes.


Martin Gallagher | Speeple: The latest news
Re: Stuck With Bad Category Filter Performance [message #3442 is a reply to message #3437 ] Sun, 17 August 2008 11:13 Go to previous message
w00t08
Messages: 2
Registered: August 2008
Junior Member
Hey, thanks for PK hints, that made sense and eliminated a "using where" in the EXPLAIN output. Smile

And other than that...? I'm not averse to table/database design changes as long as they'll deliver better performance. Unfortunately, I'm a pretty clueless as to how these could look like. Smile
Previous Topic:Connection to Mysql is down after short period
Next Topic:My MySQL datafile seems to growing alarmingly
Goto Forum:
  



Current Time: Thu Nov 20 20:05:20 EST 2008

Total time taken to generate the page: 0.01869 seconds
.:: Contact :: Home :: MySQL Support by Percona.com ::.

Powered by: FUDforum 2.7.5.
Copyright ©2001-2006 FUD Forum Bulletin Board Software

MySQL Performance | Forum authority Badge