【问题标题】:10 Million rows taking 3.50 seconds for a simple type query1000 万行简单类型查询耗时 3.50 秒
【发布时间】:2017-01-01 23:02:56
【问题描述】:

我是数据库查询优化的新手。 这是创建表查询:

CREATE TABLE mo (
  id int UNSIGNED NOT NULL auto_increment,
  msisdn varchar(20) NOT NULL,
  operatorid int UNSIGNED NOT NULL,
  shortcodeid int UNSIGNED NOT NULL,
  text varchar(100) NOT NULL,
  auth_token varchar(60) NOT NULL,
  created_at DATETIME,
  PRIMARY KEY(id)
);

我的查询是这样的:

SELECT count(id) as mo_count from mo where created_at > DATE_SUB(NOW(), INTERVAL 15 MINUTE)

当我测试它时,结果是

Time taken for tests:   3.50 seconds

[0] => Array
(
    [id] => 1
    [select_type] => SIMPLE
    [table] => mo
    [type] => ALL
    [possible_keys] => 
    [key] => 
    [key_len] => 
    [ref] => 
    [rows] => 10000255
    [Extra] => Using where
)

请教我如何优化这个查询。非常感谢。

【问题讨论】:

  • 如果此表继续增长,并且您经常查询计数,您可能会对新设计感兴趣。例如,您可以将最后的记录保存在一个非常小的“始终新鲜”表中。同时,将有一个包含所有记录的“历史”表。您还可以按特定时间段(天?)对表进行摆弄和分区,这样可以限制每个计数查询的 IO。

标签: mysql query-optimization


【解决方案1】:

您需要在用于该查询的列上添加INDEX,否则数据库必须检查表中的所有行以查看哪些行适合您的WHERE 子句。

ALTER TABLE mo ADD INDEX (created_at);

index 使 MySQL 能够根据您在该列中的数据仅扫描表的一部分。

您可以阅读有关how mysql uses indexes 的更多信息。

关于查询本身 - 在不更改表结构的情况下,您无法真正优化它(除非您知道哪个 ids 适合 WHERE,并且您可以更改查询以使用 id> X,因为id 表中的列已编入索引,但我想情况并非如此)。

【讨论】:

  • 他问的是如何优化查询,而不是模型 :-)
  • 我有点开玩笑。你的解决方案是最明显的一个;)
  • 不不,你是对的!我真的认为解释这部分也很重要:) 你可以检查更新。
  • 考虑到他们拥有的记录数量,我想说这还不错,但可以进行一些优化,正如“相关”下的问答stackoverflow.com/q/1712994/1415724 中所讨论的那样。所以德克尔的回答几乎回答了这个问题。
  • 非常感谢@Dekel。你的解释很有帮助。顺便祝大家新年快乐! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多