加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 数据库 > MySql > 正文

mysql – 创建指标的顺序会影响查询优化器将选择哪个索引?

发布时间:2020-05-27 11:29:12 所属栏目:MySql 来源:互联网
导读:如果我创建以下两个指标ALTER TABLE requests ADD INDEX daily_ips(exec_date, ip_address); ALTER TABLE requests ADD INDEX is_cached(exec_date, cached); 请求的show index输出如下Table Non_unique Ke

如果我创建以下两个指标

ALTER TABLE requests ADD INDEX daily_ips(exec_date,ip_address);
ALTER TABLE requests ADD INDEX is_cached(exec_date,cached);

请求的show index输出如下

Table       Non_unique  Key_name    Seq_in_index    Column_name Collation   Cardinality Sub_part    Packed  Null    Index_type  Comment Index_comment
requests    1           daily_ips   1               exec_date   A           413         NULL    NULL    YES BTREE       
requests    1           daily_ips   2               ip_address  A           218334      NULL    NULL    YES BTREE       
requests    1           is_cached   1               exec_date   A           165         NULL    NULL    YES BTREE       
requests    1           is_cached   2               cached      A           165         NULL    NULL    YES BTREE       

我有以下查询

EXPLAIN SELECT exec_date,100 * SUM(CASE WHEN cached = 'no' THEN 1 ELSE 0 END)  / SUM(1) cached_no,100 * SUM(CASE WHEN cached != 'no' THEN 1 ELSE 0 END)  / SUM(1) cached_yes
FROM requests
GROUP BY exec_date;

id  select_type table   type    possible_keys   key         key_len ref rows    Extra
1   SIMPLE  requests    index   NULL            daily_ips   263 NULL    436695  

但是我想强制查询优化器使用is_cached索引而不是daily_ips索引.

如果我删除daily_ips索引并再次添加它

ALTER TABLE requests DROP INDEX daily_ips;
ALTER TABLE requests ADD INDEX daily_ips(exec_date,ip_address);

然后运行相同的EXPLAIN语句,查询优化器选择is_cached索引.

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  requests    index   NULL    is_cached   6   NULL    440493  Using index

查询优化器是否期望根据添加的顺序选择索引?

如何告诉查询优化器使用哪个索引?

最佳答案 您可以指定查询运行哪个索引sholud.

试试这个:

EXPLAIN SELECT exec_date,100 * SUM(CASE WHEN cached != 'no' THEN 1 ELSE 0 END)  / SUM(1) cached_yes
FROM requests USE INDEX(is_cached)
GROUP BY exec_date;

USE INDEX和FORCE INDEX之间的差异:

通过指定USE INDEX(index_list),您可以告诉MySQL仅使用其中一个命名索引来查找表中的行.替代语法IGNORE INDEX(index_list)可用于告诉MySQL不使用某些特定索引或索引.如果EXPLAIN显示MySQL正在使用可能索引列表中的错误索引,则这些提示很有用.

您还可以使用FORCE INDEX,其作用类似于USE INDEX(index_list),但另外还假设表扫描非常昂贵.换句话说,只有在无法使用某个给定索引查找表中的行时才使用表扫描.

UPDATE

试试这个查询:

SELECT exec_date,100 * SUM(IF(cached = 0,1,0)) / SUM(1) cached_no,100 * SUM(IF(cached = 1,0)) / SUM(1) cached_yes 
FROM (SELECT exec_date,IF(cached = 'no',1) cached 
      FROM requests GROUP BY exec_date) AS A 

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读