0

我需要在 Mysql 数据库中有可变列。我使用另一种方法,即有一个辅助meta_data表。我将变量列存储在meta_data. 的结构meta_data是:

CREATE TABLE IF NOT EXISTS `data_meta` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `data_id` int(11) DEFAULT NULL,
  `meta_key` varchar(200) CHARACTER SET utf8 DEFAULT NULL,
  `meta_value` text CHARACTER SET utf8,
  PRIMARY KEY (`id`),
  KEY `data_id` (`data_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=347 ;

我需要查询其中一些变量列。所以我的问题是Mysql中这样的语句的成本是多少:

select * 
from data
join data_meta as data_prov on (data.id=data_prov.data_id)
join data_meta as data_city on (data.id=data_city.data_id)
join data_meta as data_price on (data.id=data_price.data_id)
.
.
.
.

如果在现实世界中,这可能会导致我的查询非常慢,有没有其他选择variable columns

:两者都data可以meta_data快速增长

4

1 回答 1

2

如果您的数据被正确索引,那么多个连接应该不是问题。在这种情况下,您需要一个索引data_meta(data_id, meta_key)甚至data_meta(data_id, meta_key, meta_value)

顺便说一句,我认为你忽略meta_key了逻辑

select * 
from data
join data_meta as data_prov on (data.id=data_prov.data_id and data_prov.meta_key = 'prov')
join data_meta as data_city on (data.id=data_city.data_id and data_city.meta_key = 'city')
join data_meta as data_price on (data.id=data_price.data_id and data_price.meta_key = 'price')

Assuming you only have one match per key, you can also do the query as:

select d.*,
       max(case when dm.meta_key = 'prov' then dm.meta_value end) as prov,
       . . .
from data join
     data_meta dm
     on d.id = dm.id
group by d.id;

If you are fetching the values for one meta key, this would be fine. However, MySQL tends to do joins faster than aggregation, so the join method is probably faster in general.

EDIT:

For this query to work quickly, you need to be able to lookup the meta values quickly. In MySQL, the best way to do this is using an index. This allows MySQL to lookup the values in the meta data quickly. Other databases support a technology called parallel hash joins, which would also speed up the query (and parallel hash aggregation would speed up the group by). By these are not options in MySQL, so you want to use indexing.

于 2013-08-25T12:53:52.763 回答