2012-11-25 88 views
2

我現在試着更好地解釋下面的問題和查詢的目的是什麼。 我們假設我們正在討論電子商務環境和數據庫。我們有許多其他的三個表格:產品,訂單和orders_data。 ORDERS表格將處理所有已下達的訂單和一個子表格,我們將稱之爲ORDERS_DATA將存儲訂單中記錄的所有產品。SQL查詢優化推薦產品

繼表定義,而不考慮我的問題那些無用的字段:

ORDERS (*id*, date, totale, ...); 
    ORDERS_DATA (id_order, id_product, ...); 
    PRODUCTS (id, name, ...); 

的主鍵訂單ID,而在ORDERS_DATA關鍵是(id_order,id_product)

我想用一個查詢要做的就是以檢索,給定一個產品ID(在瀏覽產品頁面或購物車頁面上爲好),基於ORDERS_DATA表提出的產品。該查詢將返回所有生命在這些訂單中的id_product,其中至少有一個這樣的產品是給定的產品ID

爲了保持一致性,我將舉例說明。假設我們在ORDERS_DATA有這些行:

R1(1, 1); R2(1, 2); R3(1, 3); R4(2, 2), R5(2, 5); R6(3, 3); 

我要爲產品編號建議= 2.我的查詢將返回的ID:1和3(從R1和R3 - 它們共享相同的訂單id和這個命令有還有產品2 - 來自R2 - btw其產品)和產品5,這要歸功於訂單號2.訂單號3將被忽略。

這是我寫的查詢,但我很肯定它不是性能和風格上最好的。

SELECT 
    A.id_product, COUNT(A.id_product) AS num 
FROM 
    orders_data A, orders_data B 
WHERE 
    A.id_order = B.id_order 
    AND B.id_product IN (*IDs-HERE*) 
    AND A.id_product NOT IN (*IDs-HERE*) 
GROUP BY A.id_product 

我已經使用INNER JOIN語法,但是性能沒有任何變化。 查詢需要0,0022sec,IN IN Clausole中只有一個產品ID。性能會隨着多個產品id而顯着減少(例如在購物車頁面中,在籃子中有更多產品)。

謝謝。

+7

[不良習慣踢:使用舊樣式的JOIN(http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/ 08/bad-habits-to-kick-using-old-style-joins.aspx) - 舊式*逗號分隔的表格樣式列表已停用ANSI - ** 92 ** SQL標準 - 停止使用它 –

+1

告訴我們執行計劃。向我們展示表格的定義(包括索引)。告訴我們它現在運行得有多快。 –

+0

請告訴我們爲什麼你需要自我加入。使用(似乎是)主鍵來將表加入自己的目的是什麼? –

回答

0

嘗試更換JOINEXISTS測試:

SELECT 
    id_product, 
    COUNT(1) As num 
FROM 
    orders_data As A 
WHERE 
    id_product NOT IN (*IDs HERE*) 
And 
    Exists 
    (
     SELECT 1 
     FROM orders_data As B 
     WHERE B.id_order = A.id_order 
     And B.id_product IN (*IDs HERE*) 
    ) 
GROUP BY 
    id_product