2013-01-04 163 views
0

我需要更新我的表中的一些行,爲簡單起見稱爲「三」。MySQL查詢優化 - 避免子查詢

我選擇列與此查詢更新:

SELECT one.id 
FROM one 
    JOIN `two` ON (one.id = two.page) 
    JOIN `three` ON (one.id = three.item) 
WHERE two.level = 1 
    AND two.item = (SELECT item FROM two WHERE page = 5 AND level = 1) 
    AND three.position > (SELECT position FROM three WHERE item = 5) 
ORDER BY three.position 

現在,我打電話與ID的,我得到一個更新查詢。

有沒有機會消除子查詢?

編輯(梅蘭妮的評論後):

表 「一」:

|id|text| 

表 「二」:

|id|item|page|level| 

表 「三化」:

|item|position| 

所以當我運行查詢

SELECT item FROM two WHERE page = 5 AND level = 1 

它將返回f.ex 1和最終WHERE子句將是:

two.item = 1 AND two.level = 1 

這是不一樣的:

two.level = 1 and two.page = 5 

我有一個表 - 一些文字與一些one.id.我需要更新表3中比我的項目(f.ex. id = 5)具有更高位置的所有項目。但是這些項目在表2中也應該具有相同的two.item,其中two.page = one.id和level = 1

對於糟糕的描述,我很抱歉。

+6

也許我在這裏失去了一些東西,但不能你用「two.pa」替換行「two.item =(SELECT item FROM two WHERE page = 5 AND level = 1)」 ge = 5「?既然你已經過濾了two.level = 1,這些在邏輯上是等價的,不是嗎? – Melanie

+1

你可以編輯你的文章的表結構,樣本數據,然後所需的結果?添加額外的細節將有助於解決您的問題。 – Taryn

+0

謝謝大家,只是增加了更多細節,我會盡量準備一些數據。 –

回答

1

您應該能夠通過,以取代那些子查詢聯接:

SELECT one.id 
FROM one 
    JOIN `two2` ON (two2.page = 5 AND two2.level = 1) 
    JOIN `two` ON (one.id = two.page AND two.item = two2.item) 
    JOIN `three2` ON (three.item = 5) 
    JOIN `three` ON (one.id = three.item AND three.position > three2.position) 
WHERE two.level = 1 
ORDER BY three.position 
+0

感謝你和每個與我共度時光的人! –

1

@TheVedge是有趣的解決方案,但不會產生相同的結果作爲查詢

我建議,以避免重複相同的表也與視圖,以便一點校正

另一個校正three2.item = 5

我建議在子查詢中限制使用0,1所以永遠不會返回一個以上的元素

SELECT one.id 
FROM one 
    JOIN `two` AS TWO2 ON (two2.page = 5 AND two2.level = 1) 
    JOIN `two` ON (one.id = two.page AND two.item = two2.item) 
    JOIN `three` AS THREE2 ON (three2.item = 5) 
    JOIN `three` ON (one.id = three.item AND three.position > three2.position) 
WHERE two.level = 1 
ORDER BY three.position 

記住,你不是在做同樣的事情與此查詢。

試試這個

CREATE TABLE `one` (
    `id` INT(10) NULL DEFAULT NULL, 
`text` VARCHAR(50) NULL DEFAULT NULL 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

_

CREATE TABLE `three` (
`item` INT(10) NULL DEFAULT NULL, 
`position` INT(10) NULL DEFAULT NULL 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

_

CREATE TABLE `two` (
`id` INT(10) NULL DEFAULT NULL, 
`item` INT(10) NULL DEFAULT NULL, 
`page` INT(10) NULL DEFAULT NULL, 
`level` INT(10) NULL DEFAULT NULL 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

_

INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (1, 1, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (3, 3, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (4, 4, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (5, 5, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (6, 6, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (7, 7, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (8, 8, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (9, 9, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (2, 2, 5, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (10, 2, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (11, 1, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (13, 3, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (14, 4, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (15, 5, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (16, 6, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (17, 7, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (18, 8, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (19, 9, 1, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (20, 2, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (21, 1, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (23, 3, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (24, 4, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (25, 5, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (26, 6, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (27, 7, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (28, 8, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (29, 9, 2, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (30, 2, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (31, 1, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (33, 3, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (34, 4, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (35, 5, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (36, 6, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (37, 7, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (38, 8, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (39, 9, 3, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (40, 2, 4, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (41, 1, 4, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (42, 3, 4, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (43, 4, 4, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (44, 5, 4, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (45, 6, 4, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (46, 7, 4, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (47, 8, 4, 1); 
    INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (48, 9, 4, 1); 

-

INSERT INTO `three` (`item`, `position`) VALUES (1, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (2, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (3, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (4, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (5, 0); 
    INSERT INTO `three` (`item`, `position`) VALUES (6, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (7, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (8, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (9, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (10, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (11, 1); 
    INSERT INTO `three` (`item`, `position`) VALUES (12, 1); 

_

INSERT INTO `one` (`id`, `text`) VALUES (1, 'A'); 
    INSERT INTO `one` (`id`, `text`) VALUES (2, 'B'); 
    INSERT INTO `one` (`id`, `text`) VALUES (3, 'C'); 
    INSERT INTO `one` (`id`, `text`) VALUES (4, 'D'); 
    INSERT INTO `one` (`id`, `text`) VALUES (5, 'E'); 
    INSERT INTO `one` (`id`, `text`) VALUES (6, 'F'); 
    INSERT INTO `one` (`id`, `text`) VALUES (7, 'G'); 

_

SELECT 
    one.id, one.text 
,two.id,two.item,two.page,two.level 
,three.item,three.position 
FROM one 
    JOIN `two` ON (one.id = two.page) 
    JOIN `three` ON (one.id = three.item) 
WHERE two.level = 1 
    AND two.item = (SELECT item FROM two WHERE page = 5 AND level = 1 limit 0,1) 
    AND three.position > (SELECT position FROM three WHERE item = 5 limit 0,1 ) 
ORDER BY three.position 




    SELECT  
one.id, one.text 
,two.id,two.item,two.page,two.level 
,three.item,three.position 
FROM one 
    JOIN `two` AS TWO2 ON (two2.page = 5 AND two2.level = 1) 
    JOIN `two` ON (one.id = two.page AND two.item = two2.item) 
    JOIN `three` AS THREE2 ON (three2.item = 5) 
    JOIN `three` ON (one.id = three.item AND three.position > three2.position) 
WHERE two.level = 1 
ORDER BY three.position 

隨着原始查詢您在TheVedge解決方案做出了選擇特定元素的您加入更多的數據 所以導致取決於你選擇什麼其他有用的分析是http://dev.mysql.com/doc/refman/5.0/en/show-profile.html並解釋

展會資料顯示,在第一次運行 原始查詢確實

Status  Duration 
starting 0.000039 
checking query cache for query 0.000144 
Opening tables 0.000032 
System lock 0.000007 
Table lock 0.000061 
init 0.000054 
optimizing 0.000314 
statistics 0.000021 
preparing 0.000051 
Creating tmp table 0.000084 
executing 0.000004 
Copying to tmp table 0.000063 
optimizing 0.000008 
statistics 0.000019 
preparing 0.000009 
executing 0.000004 
Sending data 0.000054 
optimizing 0.000008 
statistics 0.000007 
preparing 0.000009 
executing 0.000003 
Sending data 0.000126 
Sorting result 0.000030 
Sending data 0.000025 
end 0.000004 
removing tmp table 0.000011 
end 0.000005 
query end 0.000004 
freeing items 0.000101 
storing result in query cache 0.000008 
logging slow query 0.000003 
cleaning up 0.000006 

建議查詢並

Status Duration 
starting 0.000036 
checking query cache for query 0.000122 
Opening tables 0.000030 
System lock 0.000008 
Table lock 0.000064 
init 0.000046 
optimizing 0.000028 
statistics 0.000026 
preparing 0.000072 
Creating tmp table 0.000086 
executing 0.000005 
Copying to tmp table 0.001081 
Sorting result 0.000040 
Sending data 0.000056 
end 0.000005 
removing tmp table 0.000010 
end 0.000005 
query end 0.000004 
freeing items 0.000108 
storing result in query cache 0.000007 
logging slow query 0.000003 
cleaning up 0.000005 

所以,當你有充分的數據,你可以嘗試evalute更好地響應這兩個查詢

+0

謝謝,我應該再想一想。它是某種封閉表格表示,所以three.item是獨特的,也是兩個(item-book-level)。 count(one。*)= count(three。*)。對不起,投票的聲望太低了。 –

+0

一般來說,查詢並不等同,你是對的,謝謝你的通知!但是我認爲在我的情況下(你可以在閉包表中使用item作爲祖先和頁面作爲後代),查詢將產生相同的結果。再次感謝你。 –