我有两个看起来像这样的表:
表汽车
+--------+-----------+-------+---------+
| car_id | attribute | value | brand |
+--------+-----------+-------+---------+
| 1 | colore | rosso | Ferrari |
| 1 | prezzo | 100 | Ferrari |
| 2 | couleur | bleu | Renault |
| 2 | prix | 50 | Renault |
| 3 | colore | blu | Ferrari |
| 3 | prezzo | 100 | Ferrari |
+--------+-----------+-------+---------+
表翻译
+--------------------+----------------+---------+----------------------+------------------+
| original_attribute | original_value | brand | translated_attribute | translated_value |
+--------------------+----------------+---------+----------------------+------------------+
| colore | rosso | Ferrari | color | red |
| prezzo | 100 | Ferrari | price | 100 |
| colore | blu | Ferrari | color | blue |
| couleur | bleu | Renault | color | blue |
| prix | 50 | Renault | price | 50 |
+--------------------+----------------+---------+----------------------+------------------+
我正试图找到一个看起来像这样的表:
+-------------------+-------+-------------+--------------------+
| translated_car_id | color | price | translated_brand |
+-------------------+-------+-------------+--------------------+
| 1 | red | 100 | Ferrari |
| 2 | blue | 50 | Renault |
| 3 | blue | 100 | Ferrari |
+-------------------+-------+-------------+--------------------+
目前,我正在使用下面的代码。它有效,但速度极慢。
SELECT
car_id translated_car_id,
MAX(CASE
WHEN translations.translated_attribute = 'color' THEN translations.translated_value
END) color,
MAX(CASE
WHEN translations.translated_attribute = 'price' THEN translations.translated_value
END) price,
brand translated_brand
FROM
cars c
INNER JOIN
translations ON (c.attribute = translations.original_attribute
AND c.brand = translations.brand
AND c.value = relations.original_value)
GROUP BY c.car_id
任何人都知道如何使查询或结构更有效?真的很感激。
提前致谢
答案 0 :(得分:0)
我可以发现MySql没有哈希匹配,这在这里很有用。所以我假设一切都是作为嵌套循环连接完成的。
我担心的是因为没有翻译索引,对于汽车中的每一行,它都必须扫描翻译表以找到匹配的行。
我建议在翻译上使用聚集索引(original_value,brand,original_attribute)。 (ms-sql最好用最具体的第一个其他条件相同,不确定MySql)这样它就可以直接进入它需要匹配的行。这应该允许快速完成一辆车的查询。
如果您可以减少从制造商到语言的翻译,这肯定有助于翻译表的大小,但您必须确保它适用于您的数据集,因为它确实会带来一定程度的灵活性。
我认为MySql将能够使用汽车上的索引来有效地处理GROUP BY,但我会建议一个更加规范化的架构,你不需要该组。
car
-------------
car_id
brand
car_attribute
------------
car_id
attribute
value
clustered_index(car_id, attribute)
brand_attribute
------------
brand_attribute_id
brand
attribute
translated_attribute
clustered_index(brand, translated_attribute)
brand_attribute_value
------------
brand_attribute_id
value
translated_value
clustered_index(brand_attribute_id, value)
以下是这样做的查询。
SELECT
car.car_id,
color_brand_value.translated_value AS color,
price_brand_value.translated_value AS price,
car.brand
FROM
car
INNER JOIN brand_attribute AS color_brand
ON color_brand.brand = car.brand
AND color_brand.translated_attribute = 'color'
INNER JOIN car_attribute AS color_attribute
ON color_attribute.car_id = car.car_id
AND color_attribute.attribute = brand.attribute
INNER JOIN brand_attribute_value AS color_brand_value
ON color_brand_value.brand_attribute_id = color_brand.brand_attribute_id
AND color_brand_value.value = color_attribute.value
INNER JOIN brand_attribute AS price_brand
ON price_brand.brand = car.brand
AND price_brand.translated_attribute = 'price'
INNER JOIN car_attribute AS price_attribute
ON price_attribute.car_id = car.car_id
AND price_attribute.attribute = brand.attribute
INNER JOIN brand_attribute_value AS price_brand_value
ON price_brand_value.brand_attribute_id = price_brand.brand_attribute_id
AND price_brand_value.value = price_attribute.value
以这种方式这样做肯定更复杂。根据您的情况,我不确定它会更好,但如果第一个选项不够好就需要考虑。
我的背景是在mssql中,所以可能存在我不知道的差异。如果我错过了或出错了,请留言。