2016-02-26 49 views
0

嗨,我在开发一个应用程序(在Azure移动服务到IOS),用户看到产品一个接一个,我不想向用户展示他/她已经看到的产品,以便我每次他们看到任何产品时记录,而且我随机显示产品,但命令执行时间呈指数级增长,如果products_log表为空,它首先在1-2秒内执行该命令,但在将日志添加到日志表并调用命令之后执行3+秒,每次我添加越来越多的日志会成倍增长,直到它给超时在哪里在sql命令优化

这里是我的命令:

select TOP 50 * from products where id not in (select product_id from products_log where user_id = ?) and gender in (?,2) order by newid() 

下面是我从蔚蓝的移动服务控制台日志得到一个超时异常:

The request 'GET /tables/Products?userID=xxxxxxxxx&gender=x' has timed out. This could be caused by a script that fails to write to the response, or otherwise fails to return from an asynchronous call in a timely manner. 

我怎么能优化这个命令?或者你能否给我建议另一种方法?

谢谢

+2

索引怎么样?你有没有在这些桌子上?像'not in(huge_list)'这样的声明似乎不是一个好主意。改用连接。 –

+0

请提供您的执行计划('* .sqlplan') – Devart

+0

@AndyKorneyev不,我没有这些表上的任何索引,我现在看,并感谢您的建议使用连接,而不是在 – KBB

回答

3

对于此查询:

select TOP 50 p.* 
from products p 
where p.id not in (select product_id from products_log pl where pl.user_id = ?) and 
     p.gender in (?, 2) 
order by newid(); 

你可以先试试指标:products(gender, id)products_log(user_id, gender, product_id)

你也可以试试这个措辞作为not existsleft join

select TOP 50 p.* 
from products p left join 
    products_log pl 
    on p.id = pl.product_id and pl.user_id = ? and 
where p.gender in (?, 2) and pl.product_id is null 
order by newid(); 

对于此查询,相应的索引是products(gender, id)products_log(product_id, user_id)

注意:如果查询(没有top)正在返回许多行,那么order by将占据主导地位。如果是这样,你需要一个替代方法来获得50个随机行。