2013-01-04 165 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作为祖先和页面作为后代),查询将产生相同的结果。再次感谢你。 –