Mysql 解释语句说';在何处使用;使用索引&x27;如果在查询中设置了USE INDEX(),则只需说';使用where';
我有一个应用程序表,其结构如下Mysql 解释语句说';在何处使用;使用索引&x27;如果在查询中设置了USE INDEX(),则只需说';使用where';,mysql,indexing,explain,Mysql,Indexing,Explain,我有一个应用程序表,其结构如下 app_id VARCHAR(32) NOT NULL, dormant VARCHAR(6) NOT NULL, user_id INT(10) NOT NULL UNSIGNED 我在这张表上有两个索引-: combo1(UNIQUE) - app_id, user_id; combo2(INDEX) - app_id, dormant, user_id 我运行这个查询 EXPLAIN SELECT COUNT(user_id), IF
app_id VARCHAR(32) NOT NULL,
dormant VARCHAR(6) NOT NULL,
user_id INT(10) NOT NULL UNSIGNED
我在这张表上有两个索引-:
combo1(UNIQUE) - app_id, user_id;
combo2(INDEX) - app_id, dormant, user_id
我运行这个查询
EXPLAIN SELECT COUNT(user_id),
IF(user_id=1,'yes','no') FROM apps
WHERE app_id='app_2' AND dormant = 'false'
它输出以下信息-:
id -> 1;
type -> SIMPLE;
table -> apps;
possible_keys -> combo1, combo2;
key -> combo2;
key_len -> 34;
ref -> const;
rows -> 1;
Extra -> Using where
id -> 1;
type -> SIMPLE;
table -> apps;
possible_keys -> combo2;
key -> combo2;
key_len -> 42;
ref -> const,const;
rows -> 1;
Extra -> Using where; Using index
但是当我运行这个查询时
EXPLAIN SELECT COUNT(user_id),
IF(user_id=1,'yes','no')
FROM apps USE INDEX(combo2)
WHERE app_id='app_2' AND dormant = 'false'
它输出以下信息-:
id -> 1;
type -> SIMPLE;
table -> apps;
possible_keys -> combo1, combo2;
key -> combo2;
key_len -> 34;
ref -> const;
rows -> 1;
Extra -> Using where
id -> 1;
type -> SIMPLE;
table -> apps;
possible_keys -> combo2;
key -> combo2;
key_len -> 42;
ref -> const,const;
rows -> 1;
Extra -> Using where; Using index
为什么它第二次说
使用索引
,尽管它在两种情况下都使用相同的索引?来自MySQL文档:只使用索引树中的信息从表中检索列信息,而无需执行额外的查找来读取实际行。当查询仅使用作为单个索引一部分的列时,可以使用此策略 如果额外的列还显示usingwhere,则表示索引用于执行键值的查找。如果不使用where,优化器可能会读取索引以避免读取数据行,但不会将其用于查找。例如,如果索引是查询的覆盖索引,优化器可能会扫描它而不使用它进行查找
有关这方面的更多信息,您可以参考。我将回答评论中的问题:如何重写查询,使其不仅适用于
用户\u id=1
:
SELECT
COUNT(user_id) as distinct_user_count,
IF(SUM(user_id=@user_id), 'yes', 'no') as is_the_user_found
FROM apps
WHERE app_id='app_2' AND dormant = 'false';
这有点令人困惑。它不应该说使用where,因为我有一个覆盖索引。计数(user_id)应该从索引树而不是从表本身检索,因为它是索引的。原因是查询中有count(),但没有group by子句。同样来自文档:“查询只包含聚合函数(MIN(),MAX()),这些函数都是使用索引或COUNT(*)为MyISAM解析的,没有GROUP BY子句。优化器确定只应返回一行”。每一个信息都在我在回答中提到的链接上。我明白了。谢谢@Bhavik Shahyou查询实际上非常混乱,因为您同时希望得到聚合函数和简单标量函数的结果。那么@newt我该怎么办?当您删除
IF()
列时会发生什么?我使用IF函数来获取返回集中特定用户的id。如果我删除它,我将不得不运行两个不同的查询来完成我在一个查询中所做的相同工作。顺便说一句,有超过10万条记录,我的查询需要0.071秒才能得到结果。它正常还是缓慢?但您当前的查询无法解决该问题。事实上,它确实为特定的用户_id=1解决了这个问题,但它对任何其他id都不起作用,而且闻起来很黑。