繁体   English   中英

太多时间执行

[英]too much time to execute

  1. 下面的查询需要很长时间才能执行大约2分钟,请帮助我如何提高此查询的性能。
  2. 所以我们的要求是在2到3秒内获得结果。
  3. 查询也在使用索引。
  4. 但它正在执行更多扫描。

查询:

select max(`log_date`)
from `top_competitor_summary_entity`
where
  own_domain_id = 4
  and keyword_top1_count > 0
  and (grouptag_id = 0 OR grouptag_id is null);

Expalin计划:

+----+-------------+-------------------------------+------+--------------------------------------+------------------------+---------+-------+---------+-------------+
| id | select_type | table                         | type | possible_keys                        | key                    | key_len | ref   | rows    | Extra       |
+----+-------------+-------------------------------+------+--------------------------------------+------------------------+---------+-------+---------+-------------+
|  1 | SIMPLE      | top_competitor_summary_entity | ref  | own_domain_id,own_domain_id_log_date | own_domain_id_log_date | 4       | const | 2100128 | Using where |
+----+-------------+-------------------------------+------+--------------------------------------+------------------------+---------+-------+---------+-------------+
1 row in set (0.66 sec)

表结构:

mysql> show create table top_competitor_summary_entity\G
*************************** 1. row ***************************
       Table: top_competitor_summary_entity
Create Table: CREATE TABLE `top_competitor_summary_entity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `domain` varchar(255) NOT NULL COMMENT 'competitor domain name',
  `own_domain_id` int(11) NOT NULL,
  `keyword_top10_count` int(11) DEFAULT NULL,
  `keyword_top3_count` int(11) DEFAULT NULL,
  `keyword_top1_count` int(11) DEFAULT NULL,
  `keyword_top10_search_volume` bigint(20) DEFAULT NULL,
  `keyword_top3_search_volume` bigint(20) DEFAULT NULL,
  `keyword_top1_search_volume` bigint(20) DEFAULT NULL,
  `url_top10_count` int(11) DEFAULT NULL
    COMMENT 'how many competitor url in Top 10',
  `log_date` date DEFAULT NULL,
  `grouptag_id` int(11) DEFAULT '0',
  `keyword_top10_count_bing` int(11) DEFAULT '0',
  `keyword_top10_count_yahoo` int(11) DEFAULT '0',
  `keyword_top3_count_bing` int(11) DEFAULT '0',
  `keyword_top3_count_yahoo` int(11) DEFAULT '0',
  `keyword_top1_count_bing` int(11) DEFAULT '0',
  `keyword_top1_count_yahoo` int(11) DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `own_domain_id` (`own_domain_id`),
  KEY `domain_own_domain_id_log_date` (`domain`,`own_domain_id`,`log_date`),
  KEY `own_domain_id_log_date` (`own_domain_id`,`log_date`)
) ENGINE=InnoDB AUTO_INCREMENT=680592051 DEFAULT CHARSET=utf8
1 row in set (0.09 sec)

正如布兰登摩尔所说

查询本身非常简单,我不认为你可以做任何事情来通过修改它来加快速度。

你仍然可以试试这个并检查它是否有所不同

select `log_date`
from `top_competitor_summary_entity`
where
  own_domain_id = 4
  and keyword_top1_count > 0
  and (grouptag_id = 0 OR grouptag_id is null)
Order by log_date
LIMIT 0,1;

查询本身非常简单,我不认为你可以做任何事情来通过修改它来加快速度。 我仍然会好奇使用“IsNull(grouptag_id,0)= 0”是否会产生任何不同。 我对此表示怀疑,但看看它是否会削减任何东西可能会很有趣。

我认为真正的问题是,有很多记录的own_domain_id值为4,而且你没有where子句中其他字段的索引。 您可以为它们创建单独的索引和/或如果要创建专门为此查询定制的索引,则创建一个在所引用的所有4个字段上键入的索引。

其他一些观察:

如果有可能改变你的代码来处理空值(也许只是将它们视为0),那么你可以摆脱你在大多数那些字段中放置的默认值,并使它们为空。 如果没有多少字段实际上具有值0,那么这不会做太多,但是如果将很多字段设置为0,则会导致表占用更少的磁盘空间,这将转化为扫描时间更短的时间表。

您也可以水平或垂直分区表。

水平:您可以将所有top1字段放在top1表中,将所有top3字段放在top3表中,等等。或者,您可以在一个表中执行所有yahoo,在另一个表中执行所有bing; 或者可能是一个表中的所有计数字段和另一个表中的所有计数字段。 如果您发现自己通常一次只需要一组字段,那么这会缩短搜索时间,但如果您通常最终会在大多数查询中抓取所有字段,那么当然它并没有真正帮助。

垂直:这个可能比它的价值要多得多,但你可以将表中的记录分成多个表并将它们放在多个硬盘上,并同时异步查询它们。 我一直想知道谷歌是否在这些方面做了些什么。

我还注意到你使用bigint作为你的id是8个字节,而不是只有4个字节的int。 如果您认为在某些时候您将真实地处理数十亿条记录,那么bigint显然是要走的路,但是否则您可以将数据库缩小大约100兆字节,这也会使您的搜索速度稍快一些。 并且没有理由你现在不能把它变成int并且如果有必要的话将它改回bigint。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM