栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

涉及范围时,高基数列在索引中排在首位?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

涉及范围时,高基数列在索引中排在首位?

首先,让我们尝试

FORCE INDEX
选择
ef
fe
。时间太短而无法清楚地知道哪个更快,但是`EXPLAIN显示出一个不同:

首先强制范围

filetime
。(注意:顺序
WHERe
不受影响。)

mysql> EXPLAIN SELECt COUNT(*), AVG(fsize)    FROM files FORCE INDEX(fe)    WHERe ext = 'gif' AND filetime >= '2015-01-01'AND filetime <  '2015-01-01' + INTERVAL 1 MONTH;+----+-------------+-------+-------+---------------+------+---------+------+-------+-----------------------+| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows  | Extra      |+----+-------------+-------+-------+---------------+------+---------+------+-------+-----------------------+|  1 | SIMPLE      | files | range | fe | fe   | 14      | NULL | 16684 | Using index condition |+----+-------------+-------+-------+---------------+------+---------+------+-------+-----------------------+

首先强制低基数

ext

mysql> EXPLAIN SELECT COUNT(*), AVG(fsize)    FROM files FORCE INDEX(ef)    WHERe ext = 'gif' AND filetime >= '2015-01-01'AND filetime <  '2015-01-01' + INTERVAL 1 MONTH;+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra      |+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+|  1 | SIMPLE      | files | range | ef | ef   | 14      | NULL |  538 | Using index condition |+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+

显然,这种

rows
说法
ef
更好。但是,让我们检查一下Optimizer跟踪。输出相当庞大;我只展示有趣的部分。没有
FORCE
需要;
跟踪将显示两个选项,然后选择更好的。

  ...  "potential_range_indices": [     ...     {       "index": "fe",       "usable": true,       "key_parts": [         "filetime",         "ext",         "did",         "filename"       ]     },     {       "index": "ef",       "usable": true,       "key_parts": [         "ext",         "filetime",         "did",         "filename"       ]     }   ],

   "analyzing_range_alternatives": {     "range_scan_alternatives": [       {         "index": "fe",         "ranges": ["2015-01-01 00:00:00 <= filetime < 2015-02-01 00:00:00"         ],         "index_dives_for_eq_ranges": true,         "rowid_ordered": false,         "using_mrr": false,         "index_only": false,         "rows": 16684,         "cost": 20022,    <-- Here's the critical number         "chosen": true       },       {         "index": "ef",         "ranges": ["gif <= ext <= gif AND 2015-01-01 00:00:00 <= filetime < 2015-02-01 00:00:00"         ],         "index_dives_for_eq_ranges": true,         "rowid_ordered": false,         "using_mrr": false,         "index_only": false,         "rows": 538,         "cost": 646.61,    <-- Here's the critical number         "chosen": true       }     ],

          "attached_conditions_computation": [ {   "access_type_changed": {     "table": "`files`",     "index": "ef",     "old_type": "ref",     "new_type": "range",     "cause": "uses_more_keyparts"   <-- Also interesting   } }

使用

fe
(第一个范围列),可以使用范围,但它估计扫描了16684行以获得
ext='gif'

使用

ef
(低基数
ext
优先),它可以使用索引的两列并在BTree中更有效地向下钻取。然后,它发现估计有538行,所有这些行都对查询有用-
无需进一步过滤。

结论:

  • INDEX(filetime, ext)
    仅使用第一列。
  • INDEX(ext, filetime)
    使用两列。
  • 考虑基数, 将涉及
    =
    测试的列放在索引的 第一位 。 __
  • 查询计划不会超出第一个“范围”列。
  • “基数”与 复合索引和这种查询 无关。

(“使用索引条件”表示存储引擎(InnoDB)将使用索引中用于过滤的列之外的列。”)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/421316.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号