【问题标题】:Weird Index activity on mysql Joinmysql Join 上的奇怪索引活动
【发布时间】:2013-02-28 22:46:36
【问题描述】:

我有一个类似这样结构的countries 表,在 iso2 列上有一个索引:



在进行普通选择查询时,iso2 索引工作正常:



但是当加入iso2上的另一个表时,它的行为很奇怪:



首先它说NULL possible_keys 但它仍然使用它?然后它还说 256 行,这是整个表。它在大更新时运行非常慢,所以我可以看出它没有使用索引。这里有什么问题?

编辑:另外,如果我从 iso2 索引中取出 id 列(参见第一张图片),那么它会说在连接中没有使用索引。


更多信息:我一直在尝试规范化我的数据并使用country_id 而不是country。我正在用country_id 更新表格时发现它运行得很慢。一些解释让我发现索引没有被使用。也许它与 iso2 是 char(2) 有关?

我是这样填充 country_id 的:

UPDATE leads
LEFT JOIN countries on leads.country=countries.iso2
SET leads.country_id=countries.id

对于leads 表上的大约 100k 行,此查询花费了将近 40 秒。

【问题讨论】:

    标签: mysql sql phpmyadmin


    【解决方案1】:

    那个EXPLAIN表示它正在做一个全索引扫描,这并不理想,但不一定是坏的;在这种情况下,这很好。 iso2 索引是covering index,这意味着它包含该表中此查询所需的所有列。基本上,查询优化器决定与其从索引中查找所需的行,然后从表中读取该行以获取id,不如直接转到索引的下一部分,因为这样更快。

    我原以为优化器会在索引上使用引用,但显然它认为这样做没有好处。由于索引很小,我不会担心不使用索引上的引用。

    其他几点:

    • 能否请您详细说明“大更新时运行速度很慢”?
    • 表是使用 MyISAM 还是 InnoDB?
    • countries.id 可能会更改为SMALLINT UNSIGNED;这与INT(5) 几乎相同,但使用 2 个字节而不是 4 个。
    • CHAR(2)iso2 的最佳数据类型

    【讨论】:

    • 我添加了一个示例更新。它正在使用 MyISAM,但我尝试切换引擎并没有任何改变。我不明白的是,为什么SELECT 似乎只需要浏览 1 行,而连接正在进行“全索引扫描”?
    猜你喜欢
    • 2015-07-12
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 2016-01-31
    • 1970-01-01
    相关资源
    最近更新 更多