2016-11-26 154 views
0

因此,我對我的MySQL數據庫設計中的'具有多種變體的產品'模式頭痛不已。在大型數據集上的MySQL中的IFNULL的性能

我想要一張名爲base_productsproducts的表格。每product屬於base_product

product應繼承base_product的列,但也有一些列命名相同。列數據products將覆蓋base_products列,但前提是products上的列不爲NULL。

檢索產品在理論上看起來像這樣的查詢:

SELECT 
    p.id, 
    IFNULL(p.sku, _p.sku) AS sku, 
    IFNULL(p.ean, _p.ean) AS ean, 
    IFNULL(p.weight, _p.weight) AS weight 
    IFNULL(p.unit_id, _p.unit_id) AS unit_id 
FROM products AS p 
JOIN base_products as _p ON p.id = _p.product_id 
WHERE IFNULL(p.weight, _p.weight) > 500 

在這種情況下IFNULL用於查詢潛在的非常大的表。

在這種情況下,IFNULL的使用是否可以接受?或者當查詢大型數據集時這會打破性能?

+1

創建一些休虛擬數據並執行EXPLAIN以知道它將如何執行。 –

+0

我會告誡不要使用sql的任何方面,因爲它是一個繼承系統 – Drew

+0

@ user2864740我應該補充說,這也必須工作WHERE IFNULL(p.name,_p.name)='something''。它應該根據「產品」中的數據的存在真正做出選擇哪一個合作伙伴來執行。 – Boyd

回答

0

首先,我更喜歡coalesce(),因爲這是ANSI標準功能:

SELECT p.id, 
     COALESCE(p.sku, _p.sku) AS sku, 
     COALESCE(p.ean, _p.ean) AS ean, 
     COALESCE(p.weight, _p.weight) AS weight 
     COALESCE(p.unit_id, _p.unit_id) AS unit_id 
FROM products p JOIN 
    base_products _p 
    ON p.id = _p.product_id 
WHERE COALESCE(p.weight, _p.weight) > 500; 

然而,無關與性能。

此查詢中的性能問題幾乎與COALESCE()(或IFNULL())無關。這只是一個函數調用。真正的問題是JOINWHERE - 這些涉及數據的移動。 JOIN很簡單:只要確保用於JOIN的列具有索引即可。

WHERE是棘手的。如果它過濾出很多行,可能還有其他一些選擇,但它們更復雜。我會專注於JOIN索引。

+0

謝謝!只是選擇你的大腦..有沒有什麼好的方法來實現這種繼承與重寫列和讓他們在where子句,同時保持良好的表現?或者在我的應用程序代碼中做這種數據選擇會更好,並且只接受「產品」表 – Boyd

+0

@Boyd中存在的重複數據。 。 。我認爲你的方法很好。如果您確實遇到性能問題,請解決它們。否則,您可以使用視圖來避免重複的代碼。 –