2012-01-03 42 views
2

架构:为什么这个结果不能仅使用索引解决?

CREATE TABLE IF NOT EXISTS `tx_hep_homes_attributes_mm` (
    `uid_local` int(11) NOT NULL DEFAULT '0', 
    `uid_foreign` int(11) NOT NULL DEFAULT '0', 
    `tablenames` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', 
    `sorting` int(11) NOT NULL DEFAULT '0', 
    KEY `uid_local` (`uid_local`), 
    KEY `uid_foreign` (`uid_foreign`), 
    KEY `uid_local_foreign` (`uid_local`,`uid_foreign`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

样品输入:

INSERT INTO `tx_hep_homes_attributes_mm` (`uid_local`, `uid_foreign`, `tablenames`, `sorting`) VALUES 
(2, 4, '', 3), 
(2, 1, '', 2), 
(2, 2, '', 1), 
(1, 2, '', 5), 
(1, 3, '', 4), 
(1, 4, '', 3), 
(1, 7, '', 2), 
(1, 8, '', 1); 

查询:

SELECT amm.uid_local, 
     amm.uid_foreign 
FROM tx_hep_homes_attributes_mm amm 
     JOIN (SELECT 1 AS att_id 
      UNION 
      SELECT 4 AS att_id 
      UNION 
      SELECT 13 AS att_id 
      UNION 
      SELECT 22 AS att_id 
      UNION 
      SELECT 12 AS att_id)d1 
     ON d1.att_id = amm.uid_foreign 
     JOIN (SELECT 1 AS home_id 
      UNION 
      SELECT 2 AS home_id)d2 
     ON d2.home_id = amm.uid_local 
ORDER BY uid_local 

生产:

+------+---------------+-------------------+-------+------------------------------------------+--------------------+----------+-------------+-------+---------------------------------+ 
| id | select_type |  table  | type |    possible_keys    |  key   | key_len | ref  | rows |    Extra    | 
+------+---------------+-------------------+-------+------------------------------------------+--------------------+----------+-------------+-------+---------------------------------+ 
| 1 | PRIMARY  | <derived7>  | ALL | NULL          | NULL    | NULL  | NULL  | 2  | Using temporary; Using filesort | 
| 1 | PRIMARY  | amm    | ref | uid_local,uid_foreign,uid_local_foreign | uid_local_foreign | 4  | d2.home_id | 1  | Using where; Using index  | 
| 1 | PRIMARY  | <derived2>  | ALL | NULL          | NULL    | NULL  | NULL  | 5  | Using where; Using join buffer | 
| 7 | DERIVED  | NULL    | NULL | NULL          | NULL    | NULL  | NULL  | NULL | No tables used     | 
| 8 | UNION   | NULL    | NULL | NULL          | NULL    | NULL  | NULL  | NULL | No tables used     | 
| NULL | UNION RESULT | <union7,8>  | ALL | NULL          | NULL    | NULL  | NULL  | NULL |         | 
| 2 | DERIVED  | NULL    | NULL | NULL          | NULL    | NULL  | NULL  | NULL | No tables used     | 
| 3 | UNION   | NULL    | NULL | NULL          | NULL    | NULL  | NULL  | NULL | No tables used     | 
| 4 | UNION   | NULL    | NULL | NULL          | NULL    | NULL  | NULL  | NULL | No tables used     | 
| 5 | UNION   | NULL    | NULL | NULL          | NULL    | NULL  | NULL  | NULL | No tables used     | 
| 6 | UNION   | NULL    | NULL | NULL          | NULL    | NULL  | NULL  | NULL | No tables used     | 
| NULL | UNION RESULT | <union2,3,4,5,6> | ALL | NULL          | NULL    | NULL  | NULL  | NULL |         | 
+------+---------------+-------------------+-------+------------------------------------------+--------------------+----------+-------------+-------+---------------------------------+ 

正如你所看到的那样,使用文件排序,尽管它应该从复合索引中解析出来。

回答

2

如果tx_hep_homes_attributes_mm只是这里显示的9行,那么我会期望索引被忽略,因为所有的数据都将在缓存中,并且使用索引会花费更多。

当索引选择的数据量远小于表中的行数时,主要使用Indicies。这里有75%的行在结果中。

+0

此表为示例数据,这就是为什么它只有9行。但解释仍然需要展示最佳匹配。 – Pentium10 2012-01-03 13:58:57

+0

这取决于数据的大小和结果中需要的行数,因此您必须查看实际数据。 – Mark 2012-01-03 14:01:21

+1

如果索引基数较低或者行数为小。 9很小。 – 2012-01-03 14:09:16

2

如果行数不是很大,查询优化器使用表扫描而不是索引。

相关问题