用简单的选择查询理解索引
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 显示可能的键中的索引但实际上并未使用它以上是关于用简单的选择查询理解索引的主要内容,如果未能解决你的问题,请参考以下文章