【问题标题】:mysql best index order for (FK, key, value)(FK, key, value)的mysql最佳索引顺序
【发布时间】:2018-02-07 17:48:34
【问题描述】:

我有一个键值表:

id, data_id, key, value

引用数据表:

id, file_id, data

它又引用了一个文件表:

id, name

文件包含大约 10000 个条目 数据包含大约 1 亿个条目

键列有大约 100 个不同的值 value 字段有许多不同的值(字符串)

现在我想知道data_id, key, value 三列的顺序是什么 应该在我的索引中。

我感兴趣的查询会查找具有特定 file_id 和特定键值组合的数据条目。例如:

SELECT * FROM files, data, keyval
WHERE files.id = data.file_id
AND data.id = keyval.data_id
AND files.id = 999
AND keyval.key = 'revenue'
AND keyval.val = 9.99

【问题讨论】:

  • 请注意投票以“主要基于意见”结束此问题的人......如果我们根据“意见”选择要定义的索引,我们做错了。

标签: mysql indexing


【解决方案1】:

索引中列的“最佳顺序”取决于访问表的实际查询(查询)。

如果我们运行的查询中唯一的谓词是WHERE data.key = 'foo',那么最大的好处是使用以key 作为前导列的索引。

如果我们没有任何查询在 key 列上具有谓词(在 WHERE 子句或 ON 子句中),并且没有查询执行 GROUP BY data.key, ...,那么我们可能不需要将key 作为任何索引中的前导列。

有时我们会添加多个索引,具有不同的列集和顺序,以满足各种查询。

索引中列顺序的选择不仅取决于数据类型和值分布,还取决于我们计划运行的实际查询的性能要求。


编辑

添加到问题中的查询格式为:

 SELECT f.*
      , d.*
      , k.*
   FROM files f
   JOIN data d
     ON d.file_id = f.id
   JOIN keyval k
     ON k.data_id = d.id
    AND k.key     = 'revenue'
    AND k.val     = 9.99
  WHERE f.id = 999

假设
idfiles 中的主键(或唯一键),并且
iddata 中的主键(或唯一键)

我会创建索引

 ON data (file_id,id)
 ON keyval (data_id,key,val)

我会查看查询的 EXPLAIN 输出以了解查询计划以及正在使用哪些索引。


如果我们在file.id 上没有相等性,并且如果key='revenue' and val=9.99非常选择性的, 那么我们可能希望keyval 作为驾驶台。我们会确保有一个可用的索引 keyval 作为前导列,例如

ON keyval(key,val,data_id)

如果查询等同于:

 SELECT f.*
      , d.*
      , k.*
   FROM keyval k
   JOIN data
     ON d.id  = k.data_id
   JOIN files f
     ON f.id  = d.file_id
 -- AND f.id  = 999
  WHERE k.key = 'revenue'
    AND k.val = 9.99

另外,我们真的需要从 all 三个表中提取 all 列吗? 还是我们只是使用* 作为快捷方式,以避免列出我们实际需要的列?

【讨论】:

  • 抱歉,我忘了添加示例查询。我已更新问题以更清楚地说明索引要求
【解决方案2】:

键值模式很糟糕。随着您的查询越深入,您就会明白为什么。

您可以做的一件事来帮助一些是遵循提示here

另外,请通过JOIN ... ON 指定表中的关系,而不是老式的FROM a,b WHERE a.x = b.y

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多