为什么Order By不使用复合索引?

时间:2016-02-09 10:44:54

标签: mysql mysql-5.6

我有一个索引(blog_id,is_published,publication_date)。 为什么不

SELECT * FROM t WHERE blog_id = 403 AND is_published = 1 AND publication_date < '2015-02-13 13:13:00' ORDER BY publication_date LIMIT 1;

使用复合索引中的所有键?

请指出我是否假设不正确。

执行计划:

{
  "query_block": {
    "select_id": 1,
    "ordering_operation": {
      "using_filesort": false,
      "table": {
        "table_name": "t",
        "access_type": "ref",
        "possible_keys": [
          "t_ee664462",
          "t_472bc96c",
          "test"
        ],
        "key": "test",
        "used_key_parts": [
          "blog_id",
          "is_published"
        ],
        "key_length": "5",
        "ref": [
          "const",
          "const"
        ],
        "rows": 47010,
        "filtered": 100,
        "index_condition": "(publication_date < '2015-02-13 13:13:00')",
        "attached_condition": "((`blog_id` <=> 403) and (`is_published` <=> 1))"
      }
    }
  }
}

这真令人困惑。我理解前两个索引部分是使用的(blog_id,is_published),但随后使用&#34; index_condition&#34;它说它将通过publication_date过滤索引。

另外&#34; attachment_condition&#34;说,在检索完整行后,它将按blog_id和is_published过滤。 我不明白我在这里读错了什么。

通过publication_date&#34;更改&#34;顺序to&#34;按blog_id,is_published,publication_date&#34;排序没有任何区别。

如果我尝试

SELECT * FROM t WHERE blog_id = 403 AND is_published = 1 AND publication_date < '2015-02-13 13:13:00' LIMIT 1;

{
  "query_block": {
    "select_id": 1,
    "table": {
      "table_name": "t",
      "access_type": "range",
      "possible_keys": [
        "t_ee664462",
        "t_472bc96c",
        "test"
      ],
      "key": "test",
      "used_key_parts": [
        "blog_id",
        "is_published",
        "publication_date"
      ],
      "key_length": "10",
      "rows": 47010,
      "filtered": 100,
      "index_condition": "((`is_published` = 1) and (`blog_id` = 403) and (`publication_date` < '2015-02-13 13:13:00'))"
    }
  }
}

这是我所期待的。在检索完整行之前,索引将被所有关键部分过滤。

表格信息:

| Field               | Type         | Null | Key | Default | Extra       |
| id                  | int(11)      | NO   | PRI | NULL    | auto_increment |
| publication_date    | datetime     | NO   | MUL | NULL    |                |
| is_published        | tinyint(1)   | NO   |     | NULL    |                |
| blog_id             | int(11)      | NO   | MUL | NULL    |                |

指数:

| Non_unique | Key_name                                             | Seq_in_index | Column_name       | Collation | Cardinality |
|          1 | test                                                 |            1 | blog_id           | A         |         662 |
|          1 | test                                                 |            2 | is_published      | A         |         912 |
|          1 | test                                                 |            3 | publication_date  | A         |      168864 |

168864是总行数,所有列也都有简单的索引。

index_condition_pushdown已启用。

没有Limit 1,我的结果相同。

Reqular解释格式:

mysql> explain EXTENDED SELECT * FROM t WHERE `blog_id` = 403 AND `is_published` = 1 AND `publication_date` > '2015-02-13 13:13:00' ORDER BY `publication_date`;
+----+-------------+---------------------------+------+----------------------------------------------------------------------------+------+---------+-------------+-------+----------+------------------------------------+
| id | select_type | table                     | type | possible_keys                                                              | key  | key_len | ref         | rows  | filtered | Extra                              |
+----+-------------+---------------------------+------+----------------------------------------------------------------------------+------+---------+-------------+-------+----------+------------------------------------+
|  1 | SIMPLE      | t | ref  | t_ee664462,t_472bc96c,test | test | 5       | const,const | 64424 |   100.00 | Using index condition; Using where |
+----+-------------+---------------------------+------+----------------------------------------------------------------------------+------+---------+-------------+-------+----------+------------------------------------+
1 row in set, 1 warning (0.01 sec)

mysql> explain EXTENDED SELECT * FROM t WHERE `blog_id` = 403 AND `is_published` = 1 AND `publication_date` > '2015-02-13 13:13:00';
+----+-------------+---------------------------+------+----------------------------------------------------------------------------+------+---------+-------------+-------+----------+-----------------------+
| id | select_type | table                     | type | possible_keys                                                              | key  | key_len | ref         | rows  | filtered | Extra                 |
+----+-------------+---------------------------+------+----------------------------------------------------------------------------+------+---------+-------------+-------+----------+-----------------------+
|  1 | SIMPLE      | t | ref  | t_ee664462,t_472bc96c,test | test | 5       | const,const | 64424 |   100.00 | Using index condition |
+----+-------------+---------------------------+------+----------------------------------------------------------------------------+------+---------+-------------+-------+----------+-----------------------+

0 个答案:

没有答案