mysql - 低基数索引仍然会减慢查询速度

标签 mysql indexing innodb

将 MySQL 5.5 与 InnoDB 结合使用。 有一个类似的查询

    SELECT
        count(distinct a.thing_id) as new_thing_count,
        sum(b.price) as new_thing_spend
    FROM thing ii
    LEFT OUTER JOIN thing a
        ON a.customer_id = ii.customer_id
        AND a.created_at >= '2013-01-01'
        AND a.created_at <= '2013-03-31'
    JOIN whatsit b
        ON b.whatsit_id = a.original_whatsit_id
    WHERE ii.customer_id = 3

在哪里

  • thing 的基数约为 25k,其中 3.5k 属于客户 3
  • 有 12 个可能的 customer_id

现在,当我使用 customer_id 上的索引运行此查询时,大约需要 10 秒。当我删除索引时,它需要 0.03 秒。

我不明白为什么会这样。这是没有索引的解释结果:

1   SIMPLE  ii  ALL                 24937   Using where
1   SIMPLE  a   ALL                 24937   Using where; Using join buffer
1   SIMPLE  b   eq_ref  PRIMARY PRIMARY 4   db.a.original_whatsit_id    1   

这里是索引 (thing_customer)

1   SIMPLE  ii  ref thing_customer  thing_customer  4   const   3409    Using index
1   SIMPLE  a   ref thing_customer  thing_customer  4   const   3409    Using where
1   SIMPLE  b   eq_ref  PRIMARY PRIMARY 4   db.a.original_whatsit_id    1   

有人能帮我解释一下为什么这个索引在逻辑上看起来不应该的情况下会减慢速度吗?

最佳答案

当您的数据库引擎决定读取索引时,它会按顺序逐行读取。这会导致它在磁盘第 2 页读取一行,在第 4 页读取另一行,在第 1 页读取另一行,在第 2 页读取下一行,等等。

有时,来回移动使得索引无济于事——恰恰相反。

如果数据库引擎在生成查询计划时在收集和分析表统计信息方面做得不好,它可能无法识别索引产生完全碎片化的磁盘读取。这可能就是您正在经历的。

尝试分析表格以收集新的统计信息:

http://dev.mysql.com/doc/refman/5.5/en/analyze-table.html

然后在有和没有索引的情况下重试。

关于mysql - 低基数索引仍然会减慢查询速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16367706/

相关文章:

mysql - 使用 24GB 服务器的 MySQL 内存不足

mysql - Ubuntu 22.04。 MariaDB "Starting MariaDB database server mariadbd [fail]"

mysql - 为什么重音在导入我的数据库时不能正确显示?

mysql - 在 ubuntu 上安装 Allegrograph

postgresql - 未考虑 Postgres 部分索引

indexing - Neo4j 中可以接受混合类型索引吗?

python - 分组 Pandas : incompatible index of inserted column with frame index

c# - MySQL 服务器在选择 blob 时变慢,直到所有查询超时

mysql - 将 Spring Boot 应用程序连接到 Google Cloud 中的 MySQL 数据库

php - 在 php 中链接返回值