2016-02-26 71 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個隨機行。