2013-07-29 20 views
0

使用表stucture为http://sqlfiddle.com/#!2/572f9/2为什么不使用MySQL索引合并?

  1. 为什么不使用使用的索引仅仅COMPANY_ID和创建的索引?

  2. 为什么在我的机器上,使用完全相同的表结构和查询,在POSSIBLE_KEYS列中只出现company_id? MySQL版本:5.5.24-0ubuntu0.12.04.1日志(Ubuntu的)

+0

什么是数据库和客户端连接的归类?我需要这个信息,因为我认为你遇到了5.5中存在的错误。 –

+0

@FloDoe '>显示像'%collat​​ion%'这样的变量; + ---------------------- + ----------------- + |变量名|值| + ---------------------- + ----------------- + | collat​​ion_connection | utf8_unicode_ci | | collat​​ion_database | utf8_unicode_ci | | collat​​ion_server | utf8_unicode_ci | + ---------------------- + ----------------- + 3行集合(0.00秒)' –

回答

2

我很确定你运行在5.5中存在的错误并且使用5.6修复。在使用不同于utf8_general_ci的排序规则时,此处不会使用日期时间列的索引。请参阅以下链接:http://bugs.mysql.com/bug.php?id=68942http://bugs.mysql.com/bug.php?id=64998

对于在最左边部分具有日期时间值的组合索引,情况也是如此。所以一个可能的解决方案是创建一个不以datetime开头的组合索引。请使用上面的示例参阅下面的示例测试会话。

因此,在你的情况下,我会尝试像Vatev建议的那样去使用组合索引,但请记住不要使用datetime列来启动它。如果使用此索引,则将取决于优化程序。但它将被列为可能的关键。一个不同的解决方案是使用5.1.xx或5.6(只有机会对5.6.12进行验证,但是bug报告声明它不会在5.1.60中发生)。

mysql> SHOW VARIABLES LIKE "version"; 
+---------------+------------+ 
| Variable_name | Value  | 
+---------------+------------+ 
| version  | 5.5.28-log | 
+---------------+------------+ 
1 row in set (0.00 sec) 

mysql> show variables like '%collation%'; 
+----------------------+-------------------+ 
| Variable_name  | Value    | 
+----------------------+-------------------+ 
| collation_connection | utf8_general_ci | 
| collation_database | latin1_swedish_ci | 
| collation_server  | latin1_swedish_ci | 
+----------------------+-------------------+ 
3 rows in set (0.00 sec) 

mysql> CREATE TABLE tbl (
    -> id int(11) not null auto_increment PRIMARY KEY, 
    -> user_id int(11) not null, 
    -> company_id int (11) NOT NULL, 
    -> created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    -> oid int(11) NOT NULL, 
    -> did varchar(100) NOT NULL, 
    -> status int(11) NOT NULL, 
    -> KEY company_id (company_id), 
    -> KEY user_id (user_id), 
    -> KEY created (created), 
    -> KEY operator_id (oid), 
    -> KEY did (did) 
    ->); 
Query OK, 0 rows affected (0.01 sec) 

mysql> EXPLAIN SELECT DATE_FORMAT(created, '%M %d, %Y') as date, count(id) as num_accepted FROM tbl WHERE created BETWEEN '2013-06-29' AND '2013-07-30' AND company_id = 20 AND (status in (2,5)) GROUP BY `date` ORDER BY created ASC; 
+----+-------------+-------+------+--------------------+------------+---------+-------+------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys  | key  | key_len | ref | rows | Extra          | 
+----+-------------+-------+------+--------------------+------------+---------+-------+------+----------------------------------------------+ 
| 1 | SIMPLE  | tbl | ref | company_id,created | company_id | 4  | const | 1 | Using where; Using temporary; Using filesort | 
+----+-------------+-------+------+--------------------+------------+---------+-------+------+----------------------------------------------+ 
1 row in set (0.00 sec) 

mysql> SET collation_connection = utf8_unicode_ci; 
Query OK, 0 rows affected (0.00 sec) 

mysql> EXPLAIN SELECT DATE_FORMAT(created, '%M %d, %Y') as date, count(id) as num_accepted FROM tbl WHERE created BETWEEN '2013-06-29' AND '2013-07-30' AND company_id = 20 AND (status in (2,5)) GROUP BY `date` ORDER BY created ASC; 
+----+-------------+-------+------+---------------+------------+---------+-------+------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra          | 
+----+-------------+-------+------+---------------+------------+---------+-------+------+----------------------------------------------+ 
| 1 | SIMPLE  | tbl | ref | company_id | company_id | 4  | const | 1 | Using where; Using temporary; Using filesort | 
+----+-------------+-------+------+---------------+------------+---------+-------+------+----------------------------------------------+ 
1 row in set (0.00 sec) 
1

的MySQL在运行时决定取决于它使对表的统计信息使用哪个索引。根据数据选择不同的查询计划是正常的。

对于这个查询,它将不得不使用相交索引合并,这是不是非常有效,它决定(正确与否)不这样做。

如果您在(company_id,status,created)上创建索引,会更好。这样它就能够直接从索引过滤结果。

我想不出为什么只有其中一个键出现的原因(假设你确实有两个键)。