2012-02-16 26 views
1

我有以下MySQL表(表大小 - 10K左右的记录):如何使MySQL与INTEGER字段和FLOAT字段的键相交?

CREATE TABLE `tmp_index_test` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `m_id` int(11) DEFAULT NULL, 
    `r_id` int(11) DEFAULT NULL, 
    `price` float DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `m_key` (`m_id`), 
    KEY `r_key` (`r_id`), 
    KEY `price_key` (`price`) 
) ENGINE=InnoDB AUTO_INCREMENT=16390 DEFAULT CHARSET=utf8; 

正如你所看到的,我有两个整数字段(R_ID和M_ID)和一个FLOAT场(价格)。 对于这些字段中的每一个,我都有一个索引。

现在,当我运行的第一个整数和第二个条件的查询时,一切都很好:

mysql> explain select * from tmp_index_test where m_id=1 and r_id=2; 
+----+-------------+----------------+-------------+---------------+-------------+---------+------+------+-------------------------------------------+ 
| id | select_type | table   | type  | possible_keys | key   | key_len | ref | rows | Extra          | 
+----+-------------+----------------+-------------+---------------+-------------+---------+------+------+-------------------------------------------+ 
| 1 | SIMPLE  | tmp_index_test | index_merge | m_key,r_key | r_key,m_key | 5,5  | NULL | 1 | Using intersect(r_key,m_key); Using where | 
+----+-------------+----------------+-------------+---------------+-------------+---------+------+------+-------------------------------------------+ 

好像MySQL能够执行得很好,因为在使用相交(r_key ,m_key)在Extra字段中。 我不是MySQL专家,但根据我的理解,MySQL首先在索引上创建交集,然后才从表本身收集交集的结果。

然而,当我运行非常相似的查询,而是对两个整数条件,我把类似的情况在整数和浮点数,MySQL的拒绝相交的指标结果:

mysql> explain select * from tmp_index_test where m_id=3 and price=100; 
+----+-------------+----------------+------+-----------------+-----------+---------+-------+------+-------------+ 
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+----------------+------+-----------------+-----------+---------+-------+------+-------------+ 
| 1 | SIMPLE  | tmp_index_test | ref | m_key,price_key | price_key | 5  | const | 1 | Using where | 
+----+-------------+----------------+------+-----------------+-----------+---------+-------+------+-------------+ 

正如你可以看到,MySQL只决定使用价格指数。

我的第一个问题是为什么,以及如何解决它?

除此之外,我需要使用MORE符号(>)而不是等号(=)在价格上运行查询。目前解释显示,对于这样的查询,MySQL仅使用整数键。

mysql> explain select * from tmp_index_test where m_id=3 and price > 100; 
+----+-------------+----------------+------+-----------------+-------+---------+-------+------+-------------+ 
| id | select_type | table   | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+----------------+------+-----------------+-------+---------+-------+------+-------------+ 
| 1 | SIMPLE  | tmp_index_test | ref | m_key,price_key | m_key | 5  | const | 2 | Using where | 
+----+-------------+----------------+------+-----------------+-------+---------+-------+------+-------------+ 

我需要让MySQL首先做索引的交集。任何人有任何想法如何?

非常感谢!

回答

0

MySQL manual:如果连接只使用关键的最左前缀,或者如果 的键不是PRIMARY KEY或唯一索引(换句话说,如果 加入

裁判用于不能根据键值选择单个行)。如果使用的键 只匹配几行,这是一个很好的连接类型。

price不是唯一的或主要的,所以选择ref。我不相信你可以强制相交。

+0

但是,既不是m_id也不是i_id unique/primary,而是对它们使用了index_merge。任何人都知道为什么? – diemacht 2012-02-21 09:34:48

相关问题