用简单的选择查询理解索引

Posted

技术标签:

【中文标题】用简单的选择查询理解索引【英文标题】:understanding indexs with a simple select query 【发布时间】:2012-01-17 12:30:17 【问题描述】:

我正在尝试了解如何通过基本查询正确处理索引。

示例:

我的表格“testme”包含以下列:

id int primary key
username varchar(20)
data1 int
data2 int
data3 int
data_order int

如果我这样做了

select username,data1,data2 from testme where data3=5 order by data_order;

我可以使用哪种索引来加快查询速度?

我尝试在 clumns data3 和 data_order 上添加索引,但对该查询的“解释”结果显示它不使用该索引。

更新: 使用mysql集群(ndb)

【问题讨论】:

你的桌子有多大?我不确定 MySQL,但在许多 RDBMS 中,通过表扫描而不是索引来访问相对较小的表(通常少于 100,000 行)会更快。 这个表实际上很小但是这个查询出现在我的慢查询日志中 @Dems 建议的 (data3, data_order) 上的 BTREE 索引应该是最好的。 【参考方案1】:

将索引视为两件事... 1. 数据存储顺序 2. 快速查找特定数据的方法(如图书索引)

在您的示例中,在(data3, data_order) 上有一个索引将很容易找到您想要的数据,并且已经以正确的顺序拥有它。

搜索完索引后还需要去表中,获取字段username, data1, data2。因此,您也可以在索引中include 他们。这使得索引更大,使用更多的空间和稍微更多的努力来更新。但是这个成本意味着索引没有被加入到表中。它只是读取索引。

【讨论】:

【参考方案2】:

对于这个特定的查询,有两个索引会有所帮助 -

data3 上的索引(如果您确定只有 data3 等于某项的查询,则为哈希,否则使用 btree)和 data_order 上的索引(btree)

编辑:在这种情况下,单独的索引更好,因为 AFAIK mysql 并不总是为 where 和 order 语句搜索复合索引,另一个问题是,以后你不能只使用这个索引的 order (索引将用于 data3 + data_order 或仅用于 data3 作为 mysql 从最左列读取索引)

【讨论】:

你觉得两列都有一个索引怎么样? 这行不通,因为当 where 语句中同时包含两个字段时,单个索引是好的 你确定,这意味着当你有一个包含其他列的复合索引时,索引不会被使用? 哈希索引只能是唯一索引,所以这不是一个选项。会试试btree 它不从复合索引中获取任何列,但它会从最左边的列开始,所以如果你有复合索引 ( foo, bar ) 并且在 where 语句中会有 foo 和 bar 就可以了, 但如果你只有 bar,这个索引将不起作用。并且混合索引 where 和 for order by 并不是一个好习惯(事实上mysql可以分别搜索 where 和 order 语句索引)【参考方案3】:

案例的最佳索引(实际上取决于表大小和date3的基数):

CREATE INDEX yourindex ON yourtable(Data3, Data_order)
INCLUDE(username, data1, data2)

或者如果mysql不支持包含列

CREATE INDEX yourindex ON yourtable(Data3, Data_order, username, data1, data2)

为什么最好?

按直接date3 值过滤 按data_order值订购 包括所有你需要的选择列表(覆盖索引)(如果 mysql 支持包括列)

更新:

对于 small 表,优化器可能会选择使用表扫描而不是索引。

表中的数据越多,*越有可能使用索引,尤其是当索引的基数足够高时

【讨论】:

在您的示例中,INCLUDE 是什么? MySQL似乎不支持它:dev.mysql.com/doc/refman/5.1/en/create-index.html ASC 在索引定义中使人们错误地认为DESC 可能有意义。不幸的是,MySQL 还不是这样。 这只是提供了一个错误,语法没有显示 create index 命令有包含参数。 explain 显示可能的键中的索引但实际上并未使用它

以上是关于用简单的选择查询理解索引的主要内容,如果未能解决你的问题,请参考以下文章

最简单方式理解为什么MongoDB索引选择B-树,而 Mysql 选择B+树

如何使用索引优化选择查询

索引扫描时 Postgres 不使用索引是更好的选择

MySQL的B树索引与索引优化

蚂蚁面试官:MySQL索引为何选择B+树?

面试官:MySQL为何选择B+树存储索引?