使用ORDER BY对SORTING结果进行LEFT JOIN时间过长

时间:2012-04-11 15:35:02

标签: mysql sql-order-by left-join

这是我在stackoverflow中的第一个问题,通常我习惯在互联网上搜索答案,但这次我找不到这个问题的答案。

我的问题只是一个查询需要太长时间才能执行,而它是2个表之间的简单连接

我先发布我的查询然后我会发布有关我的系统的更多详细信息:

SELECT * FROM tbl_item 
LEFT JOIN (SELECT * FROM tbl_item_details) AS tbl_item_details 
ON tbl_item.item_id = tbl_item_details.item_details_item_id 
WHERE item_active = 1 ORDER BY item_views DESC LIMIT 0,5

这是我的表结构:

CREATE TABLE `tbl_item` (
`item_id` int(11) NOT NULL AUTO_INCREMENT,
`item_views` int(11) NOT NULL,
`item_active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=821 DEFAULT CHARSET=utf8

tbl_item_details:

CREATE TABLE `tbl_item_details` (
`item_details_id` int(11) NOT NULL AUTO_INCREMENT,
`item_details_title` varchar(255) NOT NULL,
`item_details_content` longtext NOT NULL,
`item_details_item_id` int(11) NOT NULL,
PRIMARY KEY (`item_details_id`),
KEY `itm_dt_itm_id` (`item_details_item_id`),
CONSTRAINT `tbl_item_details_ibfk_1` FOREIGN KEY (`itm_dt_itm_id`) REFERENCES `tbl_item` (`itm_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=364 DEFAULT CHARSET=utf8

这里是EXPLAIN查询输出:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   PRIMARY     tbl_item    ALL     NULL    NULL    NULL    NULL    358     Using where; Using temporary; Using filesort
1   PRIMARY       ALL     NULL    NULL    NULL    NULL    358      
2   DERIVED     tbl_item_details    ALL     NULL    NULL    NULL    NULL    422      

每个表只有350行,而大表(tbl_item_details)是1.5 MB,因此您看到表格非常小​​。

基本上,上述查询在以下系统上执行需要将近4秒钟:

CPU:Intel(R)Pentium(R)4 CPU 3.20GHz(2个CPU),~3.2GHz RAM:3 GB Mysql:5.1.33(包含在wamp中)

之前,任何人都建议这里的解决方案是我尝试过的,有效的,有效的是什么:

有效的方法和查询花费的时间少得多(0.06秒):

  • 我尝试删除ORDER BY,我尝试从
  • 中删除item_details_content
  • 我尝试使用INNER JOIN的选择而且它尝试了
  • 切换连接中的表,使INNER表变为OUTER,反之亦然

我不能使用INNER JOIN,因为tbl_item中的行可能没有tbl_item_details中的匹配项并且我想要这些记录

我试过的东西不起作用:

  • 我尝试为item_views添加索引(DID NOT WORK)
  • 我尝试删除外键约束
  • 我尝试将桌面引擎用于MyIsam

显然当mysql在item_details_content中对日期和面(相对)大数据进行排序时会出现问题,因此如果我们摆脱其中一项(排序或列item_details_content),它就可以正常工作。

但问题是,这不应该发生!因为它只有350行,总共1.5 MB,所以该表的数据非常小! mysql应该能够处理比这更多的数据。

请注意,在建议对查询结构进行重大更改之前,我担心这是不可能的,因为我已经在这个框架上工作了一段时间并且查询是动态生成的,对查询的更改可能意味着几天工作,但总是欢迎你的建议。

P.S:我在一个功能强大的服务器(核心i7和8 GB RAM)上尝试了这个查询,花了0.3秒,这对于这样的数据库来说还是太长了

万分感谢

1 个答案:

答案 0 :(得分:2)

你试过了吗?

SELECT * FROM tbl_item 
LEFT JOIN tbl_item_details 
ON tbl_item.item_id = tbl_item_details.item_details_item_id 
WHERE item_active = 1 ORDER BY item_views DESC LIMIT 0,5

我真的认为你不需要从tbl_item_details中选择*的嵌套子查询 - 只需使用该表。