Question

the following query takes too long although there are not too many products in the table. If i query it without inner join every thing is fine. Can please someone help to find the problem or optimize this query.

SELECT P.ID AS ID, 
IFNULL(P.MIN_PRICE, 0) AS PRICE_MIN, 
IFNULL(P.MAX_PRICE, 0) AS PRICE_MAX, 
IFNULL(P.STORE_COUNT, 0) AS STORE_COUNT, 
P.TITLE AS TITLE, 
'' AS DETAIL, 
P.MANUFACTURER
FROM PRODUCT P 
INNER JOIN PRODUCT P1 on (P1.ID=P.PARENT_ID) OR (P.ID=P1.ID) WHERE P.PARENT_ID=0 AND P.ISVALID='Y' AND P1.CATEGORY_ID IN (2040)

here is the table structure:

CREATE TABLE IF NOT EXISTS `PRODUCT` (
`ID` int(11) unsigned NOT NULL DEFAULT '0',
`CATEGORY_ID` int(11) unsigned NOT NULL DEFAULT '0',
`TITLE` varchar(255) NOT NULL DEFAULT ' ',
`FILENAME` varchar(255) DEFAULT ' ',
`MANUFACTURER` int(11) unsigned NOT NULL DEFAULT '0',
`EAN_UPC` varchar(100) DEFAULT '',
`MIN_PRICE` decimal(9,2) DEFAULT '0.00',
`MAX_PRICE` decimal(9,2) DEFAULT '0.00',
`STORE_COUNT` int(11) unsigned DEFAULT '0',
`ISVALID` enum('Y','N') NOT NULL DEFAULT 'Y',
`FEATURES_SELECTED` enum('Y','N') NOT NULL DEFAULT 'N',
`PARENT_ID` int(11) DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `IndexCATEGORY_ID` (`CATEGORY_ID`),
KEY `IndexFILENAME` (`FILENAME`),
KEY `IndexMANUFACTURER` (`MANUFACTURER`),
KEY `IndexISVALID` (`ISVALID`),
KEY `IndexCOMP1` (`ID`,`ISVALID`),
KEY `IndexORDER_BY` (`CATEGORY_ID`,`ISVALID`,`STORE_COUNT`),
KEY `IndexTOTAL` (`CATEGORY_ID`,`ISVALID`),
KEY `IndexPARENT_ID` (`PARENT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Edit: I try to get all the products in a category or its subcategories. Some products have parents: lets say a jeans in 10 different sizes. Other are without parent but they are not a child either (orphan): let say a scarf without any variants. Now if i remove the OR i only get the jeans because the first condition in join is met. But it wont return the scarf, although it is a valid product in that category.

Edit: @BhupeshC here some data (CATEGORY_ID=2040):

ID   PARENT_ID TITLE 
1    0         Dress blue
2    1         Dress blue XS
3    1         Dress blue S
4    1         Dress blue M
5    0         Dress Yellow
6    5         Dress Yellow M
7    5         Dress Yellow L
8    5         Dress Yellow XL
9    0         Scarf men
10   0         Scarf women

rest of columns can be set to default. Expected result:

ID   PARENT_ID TITLE 
1    0         Dress blue
5    0         Dress Yellow
9    0         Scarf men
10   0         Scarf women

Edit: when i look to the data, i think somebody will say just query products with parent_id=0. Please don´t do that. Because i have just simplified the query. in the original query it is possible to filter the data based on informations that can be only found on child products but that will make the question more complicated. eg. i want just show products available in size XL. But the UNION approach of DrewB might work, i just want to see if there is better solution.

Thanks for Help.

No correct solution

OTHER TIPS

You problem is the OR in the inner join. It makes it a much more expensive join. You can see the impact by using EXPLAIN https://dev.mysql.com/doc/refman/5.0/en/using-explain.html.

Try this : -

SELECT P.ID AS ID, 
IFNULL(P.MIN_PRICE, 0) AS PRICE_MIN, 
IFNULL(P.MAX_PRICE, 0) AS PRICE_MAX, 
IFNULL(P.STORE_COUNT, 0) AS STORE_COUNT, 
P.TITLE AS TITLE, 
'' AS DETAIL, 
P.MANUFACTURER
FROM PRODUCT P 
LEFT JOIN PRODUCT P1 on (P1.ID=P.PARENT_ID) WHERE P.PARENT_ID=0 AND P.ISVALID='Y' AND P1.CATEGORY_ID IN (2040)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top