【问题标题】:select count(*) query is too slow. I'm guess it is not work by indexingselect count(*) 查询太慢。我猜它不能通过索引来工作
【发布时间】:2020-04-12 18:34:00
【问题描述】:

我想征求意见,因为我做了更好的搜索。

我的服务器环境如下。

  • CentOS 5.1 版
  • Linux 2.6,18
  • CPU:Intel (R) Xeon (R) CPU E3-1230 v3 @ 3.30GHz 8core
  • M / M:8 GB
  • MySQL v5.5.40

此表(kc_article-MyISAM)中大约有 260,000 条记录。

 mysql> desc kc_article;

+ --------------------- + ---------------------- + ---- -+ ----- + --------------------- + ---------------- +

| Field | Type | Null | Key | Default | Extra |

+ --------------------- + ---------------------- + ---- -+ ----- + --------------------- + ---------------- +

| idx | int (11) | NO | PRI | NULL | auto_increment |

| w_status | tinyint (4) | NO | MUL | 1 | |

| w_subj | varchar (255) | NO | MUL | NULL | |

~~ omission ~~

| w_section1 | int (11) | NO | MUL | NULL | |

| w_section2 | int (11) | NO | MUL | NULL | |

| w_theme | int (11) | NO | MUL | NULL | |

~~ Lay ~~

即使在查询条件下创建索引,速度有时也会超过 1、2、10 或 20 秒。 w_status 和 w_section2 都已编入索引。

mysql> explain select count (*) as cnt from kc_article
       where w_status> 5
         and (w_section2 = '68')

+ ---- + ------------- + ------------ + ------ + ---------- ----------- + ------------ + --------- + ------- + ------- + ------------- +

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+ ---- + ------------- + ------------ + ------ + ---------- ----------- + ------------ + --------- + ------- + ------- + ------------- +

| 1 | SIMPLE | kc_article | ref | w_section2, w_status | w_section2 | 4 | const | 33548 | Using where |

+ ---- + ------------- + ------------ + ------ + ---------- ----------- + ------------ + --------- + ------- + ------- + ------------- +

检查、恢复和优化表以及删除索引后重新创建表也是如此。 w_status的取值为0到6的整数,6为95%以上。

期待您的来信。

【问题讨论】:

  • kc_article 表上的实际索引设置是什么?
  • 您没有在问题中显示任何索引。该查询不使用主键,即实际索引的唯一列。短语the index is created in the query condition 很奇怪:索引由查询使用,它们不是由它们创建的。创建或更改表时必须显式创建索引。
  • BTW MySQL 5.5 非常老旧。您可能会遇到在更高版本中修复的问题。 260K 不是很多数据,它实际上相当小。也许与尝试访问同一个表的其他连接存在争用?如果你有很多更新或插入,扫描整个表的SELECT 将被每个人阻止。 20 秒可能是 MySQL 锁定所有行以计算计数所需的时间。索引也会减少阻塞
  • 请在您的测试完成后确认 GMB 的回答是否有用。我们看到您无法使用此新登录方式投票或接受答案。欢迎来到 stackoverflow.com

标签: mysql linux centos5 mysql5


【解决方案1】:

首先,这个查询:

select count (*) as cnt from kc_article where w_status> 5 and (w_section2 = '68')

应该写成:

select count (*) as cnt from kc_article where w_status =  and w_section2 = 68

括号是多余的,因为w_section2 是一个整数,所以它应该与一个整数而不是字符串进行比较。此外,w_status 的范围从 0 到 6,因此您可以使用相等条件而不是不等式。

您提到 w_status 和 w_section2 都已编入索引。对于此查询,您希望在两列上都有一个复合索引,而不是在每列上都有一个索引(否则,MySQL 不能同时使用两者)。如果不存在,则创建它:

create index kc_article_status_section_idx on kc_article(w_status, w_section2);

几十万行并不是一个大数据集,我希望您的查询应该使用上述索引快速运行。

【讨论】:

  • 您的回复对我很有帮助。
【解决方案2】:

select count (1) as cnt from kc_article where w_status> 5 and w_section2 = '68'

【讨论】:

  • COUNT(1)COUNT(*) 的执行方式相同。 COUNT(col) 的不同之处在于它仅在 col 不是 NULL 时才有效。
【解决方案3】:

这个复合索引,按这个顺序就是你需要的:

INDEX(w_secdion2, w_status)

在构建索引时,开始使用= 子句。见http://mysql.rjweb.org/doc.php/index_cookbook_mysql

【讨论】:

    猜你喜欢
    • 2012-09-26
    • 1970-01-01
    • 2012-10-29
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    相关资源
    最近更新 更多