Jump to content

how can I make this SELECT query more efficient?


bitt3n

Recommended Posts

The following query executes in 3.6 seconds on a products table of 475K rows (returning ~1K rows). I would like to make it more efficient.

 

SELECT p.*, shop
FROM products p
JOIN users u ON p.`date` >= u.prior_login and u.user_id = 22
JOIN shops s ON p.shop_id = s.shop_id
ORDER BY shop, `date`, product_id;

 

on the product table I have indexes on (product_id), (date), (product_id,date),(shop_id,date). on the shops table I have an index on (shop_id).

 

If I remove from the ORDER BY clause both date and product_id, the query executes in 0.06 seconds. If I add either of those columns back to the ORDER BY, execution time goes back to 3.6 seconds.

 

I notice if I remove the first JOIN, the query executes in 7.4 seconds (returning all 475K rows). I am running MySQL client version: 5.0.67.

Link to comment
Share on other sites

add an explain in front of your select, like this:

 

EXPLAIN SELECT p.*, shop
FROM products p
JOIN users u ON p.`date` >= u.prior_login and u.user_id = 22
JOIN shops s ON p.shop_id = s.shop_id
ORDER BY shop, `date`, product_id;

 

Post the results.

 

sure, here it is

 

id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	u	const	PRIMARY,prior_login	PRIMARY	4	const	1	Using temporary; Using filesort
1	SIMPLE	s	ALL	PRIMARY	NULL	NULL	NULL	90	 
1	SIMPLE	p	ref	shop_id,date,shop_id_2,shop_id_3	shop_id	4	db.s.shop_id	4761	Using where

Link to comment
Share on other sites

I see that your shops table isn't using an index, though I don't know if that will fix the speed because you say it is faster without the order by.

 

But, an order by is the last thing to run in your code, first it needs to select all the data that it needs, then it needs to go through all that data again to choose the order it needs to return it in, it is almost like running 2 queries, but then again you have 3 orders, so it needs to order it 3 times. order by is a slow operation, and there is nothing via MySQL to speed it up, so if you remove it and order it using php it could speed things up.

Link to comment
Share on other sites

You're missing an index on the "s" table.

someone else observed this -- I'm confused why it says this, since I do have an index on that table.

 

these are the keys on my products table

Keyname Type    Cardinality     Action  Field
PRIMARY  PRIMARY     476122              product_id
shop_id  UNIQUE  476122              shop_id,link
title_2  UNIQUE  476122              title,image
brand    INDEX   8983            brand
title    INDEX   238061              title
date     INDEX   158707              date
shop_id_2    INDEX   90              shop_id
product_id   INDEX   476122          product_id,date
shop_id_3    INDEX   158707          shop_id,date

 

so index named shop_id_2 is the shop_id index. on shops, the index is

Keyname   Type  Cardinality Action  Field
PRIMARY   PRIMARY    90              shop_id

 

this should be ok, right?

 

also here are the SHOW CREATE tables

 

CREATE TABLE `products` (\n  `product_id` int(10) NOT NULL auto_increment,\n  `shop_id` int(10) NOT NULL default '0',\n  `title` varchar(120) NOT NULL default '',\n  `brand` varchar(80) NOT NULL default '',\n  `price` float NOT NULL default '0',\n  `image` varchar(255) NOT NULL default '',\n  `image_height` smallint(6) default NULL,\n  `image_width` smallint(6) default NULL,\n  `link` varchar(255) NOT NULL default '',\n  `date` datetime NOT NULL default '0000-00-00 00:00:00',\n  PRIMARY KEY  (`product_id`),\n  UNIQUE KEY `shop_id` (`shop_id`,`link`),\n  UNIQUE KEY `title_2` (`title`,`image`),\n  KEY `brand` (`brand`),\n  KEY `title` (`title`),\n  KEY `date` (`date`),\n  KEY `shop_id_2` (`shop_id`),\n  KEY `product_id` (`product_id`,`date`),\n  KEY `shop_id_3` (`shop_id`,`date`)\n) ENGINE=MyISAM AUTO_INCREMENT=547387 DEFAULT CHARSET=latin1

 

CREATE TABLE `shops` (\n  `shop_id` int(10) NOT NULL auto_increment,\n  `shop` varchar(80) NOT NULL default '',\n  `last_look` datetime NOT NULL default '0000-00-00 00:00:00',\n  PRIMARY KEY  (`shop_id`)\n) ENGINE=MyISAM AUTO_INCREMENT=142 DEFAULT CHARSET=latin1

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.