2014-03-04 76 views
0

儘管表中沒有太多產品,但以下查詢需要的時間太長。 如果我沒有內部聯接查詢它,每件事情都很好。可以請某人幫忙查找問題或優化此查詢。帶內連接的MySQL查詢需要很長時間

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) 

這裏是表結構:

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; 

編輯: 我試圖讓一個類別或子類別的所有產品。有些產品有父母:可以說10種不同尺寸的牛仔褲。其他沒有父母,但他們也不是孩子(孤兒):讓我們說一個沒有任何變種的圍巾。現在,如果我刪除或我只收到牛仔褲,因爲在加入的第一個條件得到滿足。但它不會退回圍巾,雖然它是該類別的有效產品。

編輯: @BhupeshC這裏的一些數據(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 

列的其餘部分可以被設置爲默認值。 預期結果:

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

編輯:當我看到這些數據,我想有人會說只是查詢產品PARENT_ID = 0。請不要這樣做。因爲我剛纔簡化了查詢。在原始查詢中,可以根據只能在兒童產品上找到的信息來過濾數據,但這會使問題更加複雜。例如。我只想展示XL尺寸的產品。 但是DrewB的UNION方法可能工作,我只想看看是否有更好的解決方案。

感謝您的幫助。

+0

能否請您解釋一下你正在嘗試這樣做,這個查詢可以重新wrtten沒有或? – Ram

回答

0

你的問題是內連接的OR。它使它成爲一個更加昂貴的連接。您可以使用EXPLAIN https://dev.mysql.com/doc/refman/5.0/en/using-explain.html來查看影響。

+0

謝謝,但我需要或因爲我想只顯示父母,但有些產品沒有父母。有什麼方法可以在沒有OR的情況下獲得我所需要的? – matrixx

+1

很難說,不知道更多關於數據的信息,但有時您可以使用UNION刪除OR。因此,寫2個不同的查詢(OR的每個部分一個)和UNION結果。 – DrewB

0

試試這個: -

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) 
+0

如果我這樣做,它不會返回孤兒產品。在這種情況下,我不需要任何聯接,簡單的查詢就足夠了。 – matrixx

+0

如果您可以提供一些帶有預期結果集的樣本數據嗎? – KrazzyNefarious