2016-11-26 532 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中存在的重复数据。 。 。我认为你的方法很好。如果您确实遇到性能问题,请解决它们。否则,您可以使用视图来避免重复的代码。 –