【问题标题】:SELECT COUNT not using indexSELECT COUNT 不使用索引
【发布时间】:2014-12-09 11:13:25
【问题描述】:

select count(*) 有问题,因为太慢了,我不知道为什么:

表格:tabla_maestra(800 万个寄存器)

索引:“codigo_postal”列上的“codigo_postal”,它是一个 char(5)

查询

SELECT COUNT(*) AS total
FROM tabla_maestra tm
WHERE (tm.nombre like '%name%' OR tm.empresa_apellido1 like '%enterprise_name%') AND
      (tm.codigo_postal like '08%');

此查询花费的时间太长(大约 4 秒),因为它没有使用任何索引。也就是说,这个查询是在做一次全扫描(800 万个寄存器)。谁能解释一下为什么?

我已将此查询重写为:

SELECT COUNT(*) AS total
FROM tabla_maestra tm FORCE INDEX (codigo_postal)
WHERE (tm.nombre like '%javier%' OR tm.empresa_apellido1 like '%javier%') AND
      (tm.codigo_postal like '08%');

现在,此查询使用“codigo_postal”索引,但它更慢:8 秒而不是 4 秒!!!

我什么都不懂,谁能帮帮我吗?
我将不胜感激。谢谢,
丹妮。

【问题讨论】:

  • 查看 SHOW CREATE TABLE 和 EXPLAIN 两个查询的输出将有助于...
  • 这里有两个简洁的工具可以帮助您更深入地了解 mysql 正在做什么: (a) EXPLAIN:只需在每个查询前面加上“explain extended”并运行它。 MySQL 将输出它计划使用的索引和一些其他有用的信息。 (b) PROFILING:首先开启profiling“set profiling=1;”然后运行您的查询。然后“显示个人资料;”和(假设您的查询是列表中的第一名)“显示查询 1 的配置文件;”如果您想了解更多信息,请在此处发布您的结果。
  • “较慢”部分可能是因为优化器立即正确选择了全表扫描,而不是首先通过在codigo_postal 上的索引扫描查找候选行,然后随机读取使用找到的候选行用于检查其余查询条件的索引。那些随机访问辅助查找可能会花费很多。为了改进事情,您需要对 WHERE 中使用的所有三列都有一个覆盖索引,以便可以单独通过索引扫描检索结果,或者每列上的索引和优化器索引合并足够聪明以利用这个...
  • 谢谢大家。问题是我无法在其他列中建立索引,因为条件是:像'%pattern%' 这样的列。我错了吗?

标签: mysql performance count indexing where


【解决方案1】:

两个查询的解释输出是:

【讨论】:

    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 2020-04-12
    相关资源
    最近更新 更多