2012-12-05 238 views
1

我有一个用户已购买的项目表,其中有一个类别标识符。所以,我想向用户展示来自同一个表的其他商品,其中已经有相同的商品类别。SQL select ... in(select ...)花费很长时间

查询我试图超过22秒运行和主要项目表甚至没有3000行......为什么这么低效?我应该索引,如果是的话,哪些列?

这里的查询:

select * from items 
    where category in (
     select category from items 
     where ((user_id = '63') AND (category <> '0')) 
     group by category 
    ) 
order by dateadded desc limit 20 
+1

是的,你应该索引的,并且您将使用在您的查询的标识符中的所有列。在这个例子中,你想索引'category'和'dateadded',如果还没有PK/index:'user_id'。 –

+0

@BenAshton @BenAshton谢谢,将尝试 - 已经PK user_id指出 –

回答

1

下面是一个查询。并确保在categoryuser_id添加索引,dateadded

select i1.* 
from items i1 
inner join 
(select distinct 
      category 
     from items 
     where ((user_id = '63') AND (category <> '0')) 
) i2 on (i1.Category=i2.Category) 


order by i1.dateadded desc limit 20 
+1

从22秒到0.156秒 - 非常感谢,非常感谢 –

0

如果指数category并可能dateadded,因此应加快了一点东西。

1

尝试使用自连接以提高性能为:

select i1.* from items i1 JOIN items i2 on i1.category= i2.category 
where i2.user_id = '63' AND i2.category <> '0' 
group by i2.category 
order by i1.dateadded desc limit 20 

加入比嵌套子查询快得多。

编辑:尝试没有group by为:

select i1.* from items i1 JOIN items i2 on i1.category= i2.category 
where i2.user_id = '63' AND i2.category <> '0' 
order by i1.dateadded desc limit 20 
+0

这是不正确的 - 它只是返回一个项目每个类别 - 因此,用户已购买18个类别,这只显示18个结果,每个类别 –

+0

@DarrenSweeney:在这种情况下,尝试删除'group by'后。 –

+0

已经这样做了,生成了同一个项目的18个副本 –

1

合适的地方放一个指标,如果有必要将是对dateaddeduser_id和/或category

+0

不,因为那样只会显示用户已经拥有的项目 - 我希望从表格中查看所有项目,无论他们是否具有这些项目 - 其他项目 –

+0

我认为你错过了行 –

+0

@DarrenSweeney是的,你是对的,我错读了,现在重新阅读它。我现在编辑它。我认为“YogendraSingh”有一个很好的答案 – tristankoffee