使用索引满足MySQL条件 请考虑以下模式 CREATE table articles ( id Int UNSIGNED NOT NULL AUTO_INCREMENT, cat_id Int UNSIGNED NOT NULL, status Int UNSIGNED NOT NULL, date_added Datetime, Primary Key (id)) ENGINE = InnoDB; CREATE INDEX cat_list_INX ON articles (cat_id, status, date_added); CREATE INDEX categories_list_INX ON articles (cat_id, status);

使用索引满足MySQL条件 请考虑以下模式 CREATE table articles ( id Int UNSIGNED NOT NULL AUTO_INCREMENT, cat_id Int UNSIGNED NOT NULL, status Int UNSIGNED NOT NULL, date_added Datetime, Primary Key (id)) ENGINE = InnoDB; CREATE INDEX cat_list_INX ON articles (cat_id, status, date_added); CREATE INDEX categories_list_INX ON articles (cat_id, status);,mysql,indexing,Mysql,Indexing,我已经写了以下两个查询,这两个查询完全可以通过上面的两个标记得到满足,但是MySQL在额外的列中添加了where mysql> EXPLAIN SELECT cat_id FROM articles USE INDEX (cat_list_INX) WHERE cat_id=158 AND status=2 ORDER BY date_added DESC LIMIT 500, 5; +----+-------------+----------+------+---------------

我已经写了以下两个查询,这两个查询完全可以通过上面的两个标记得到满足,但是MySQL在额外的列中添加了where

mysql> EXPLAIN SELECT cat_id FROM articles USE INDEX (cat_list_INX) WHERE cat_id=158 AND status=2 ORDER BY date_added DESC LIMIT 500, 5;
+----+-------------+----------+------+---------------+--------------+---------+-------------+-------+--------------------------+
| id | select_type | table  ref         |   | type | possible_keys | key          | key_len | rows  | Extra                    |
+----+-------------+----------+------+---------------+--------------+---------+-------------+-------+--------------------------+
|  1 | SIMPLE      | articles | ref  | cat_list_INX  | cat_list_INX | 5       | const,const | 50698 | Using where; Using index |
+----+-------------+----------+------+---------------+--------------+---------+-------------+-------+--------------------------+


mysql> EXPLAIN SELECT cat_id FROM articles USE INDEX (categories_list_INX) WHERE cat_id=158 AND status=2;
+----+-------------+----------+------+---------------------+---------------------+---------+-------------+-------+--------------------------+
| id | select_type | tab key                 |le    | type | possible_keys       | key_len | ref         | rows  | Extra                    |
+----+-------------+----------+------+---------------------+---------------------+---------+-------------+-------+--------------------------+
|  1 | SIMPLE      | articles | ref  | categories_list_INX | categories_list_INX | 5       | const,const | 52710 | Using where; Using index |
+----+-------------+----------+------+---------------------+---------------------+---------+-------------+-------+--------------------------+

据我所知,何处需要额外的磁盘搜索。为什么不使用索引?

第一个查询是在存储引擎之外的mysql级别过滤记录,因为您的“ORDER BY”子句使用了date\u added字段

通过将date_added字段移动到索引中的第一个位置,可以缓解这种情况,如下所示

CREATE INDEX cat_list_INX ON articles (date_added, cat_id, status);
第二个查询-我的mysql版本没有显示“使用where”-我也不希望-可能是因为我没有记录

mysql> EXPLAIN SELECT cat_id FROM articles USE INDEX (categories_list_INX) WHERE cat_id=158 AND status=2;
+----+-------------+----------+------+---------------------+---------------------+---------+-------------+------+-------------+
| id | select_type | table    | type | possible_keys       | key                 | key_len | ref         | rows | Extra       |
+----+-------------+----------+------+---------------------+---------------------+---------+-------------+------+-------------+
|  1 | SIMPLE      | articles | ref  | categories_list_INX | categories_list_INX | 8       | const,const |    1 | Using index |
+----+-------------+----------+------+---------------------+---------------------+---------+-------------+------+-------------+
1 row in set (0.00 sec)
来自高性能MySQL的额外列信息:

使用索引:这表示MySQL将使用覆盖索引来避免访问表。不要混淆覆盖索引和索引访问类型


使用Where:这意味着MySQL服务器将在存储引擎检索到筛选行后发布它们。存储引擎在读取索引时(和如果)可以检查索引中涉及列的许多WHERE条件,因此并非所有带有WHERE子句的查询都会显示“使用WHERE”。有时,“Using where”的出现暗示查询可以从不同的索引中获益。

非常确定第一个查询是因为您的order by/limit用法。还在第二次查询中尝试了解它的用法-到目前为止,我同意你的看法,你运行的是什么mysql版本?你们不认为表类型应该是索引而不是ref吗?我从源代码运行5.5.15。根据高性能Mysql,type-ref优于index。索引是索引扫描(和/或覆盖索引读取)。Ref仍然是一个索引扫描-但是只返回一行(如果不是unqiue,则返回多行),感谢您的解释。你能告诉我如何解释第一个查询中的“使用where;使用index”吗?mabey修改第一个索引可能有助于:在文章上创建索引cat\u list\u INX(添加日期、cat\u id、状态);现在我看到505行而不是50698行,我想知道为什么要先添加日期?