代码之家  ›  专栏  ›  技术社区  ›  codeNinja

在带有索引的查询中添加where子句大大降低了速度

  •  1
  • codeNinja  · 技术社区  · 11 年前

    我有一张有640k张唱片的桌子。有一列名为 COUNTRY_CD 。始终设置为 USA 。上有一个索引 国家_CD

    我运行了以下查询,耗时6秒

    select sum(ga) from sales_data
    

    运行了以下查询,耗时40秒

    Select sum(ga) from sales_data where country_cd='usa'
    

    正如我所说 country_cd 。为什么运行第二个查询需要这么多时间?


    更新:

    我增加了innodb_buffer_pool_size。第一个查询现在在1秒内运行,第二个查询在6秒内运行。我还能做什么呢。我真的需要它们是1秒以下的查询。

    1 回复  |  直到 11 年前
        1
  •  3
  •   dognose    11 年前

    虽然您的总体性能相当缓慢,但差异的原因可能是mysql使用索引的方式。

    如果运行查询时没有 where -子句,mysql执行全表扫描以汇总值。通常mysql现在是 阅读 按照插入顺序从数据表中删除,导致 顺序磁盘i/o。 (快速)

    当您使用 哪里 -子句,mysql将使用该索引。因此,它将开始处理索引 依次地 但对于每个匹配,它都会查找 ga 实际数据表中的值,然后导致 随机磁盘i/o

    下面是一个很好的例子,说明顺序磁盘访问如何比使用索引(和随机磁盘访问)快得多: https://www.percona.com/blog/2012/11/23/full-table-scan-vs-full-index-scan-performance/

    当使用非常糟糕的索引时,该示例显示了大约相同的关系(慢6倍)——如果每个数据行包含相同的值,则索引就是这样。

    链接还概述了,这只在表不适合内存时才重要(也许您的开发机器没有给mysql足够的内存?)


    我只是通读了这里的评论,关于是否真的有顺序磁盘io的大讨论。我不能肯定这一点,但至少结果和与内存操作相比的差异表明,FULL-TABLE的访问 如果尚未将表加载到内存中,则比基于索引访问表更快。