查询:
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);
海外计划:
+----+-------------+-------------------------------+------+--------------------------------------+------------------------+---------+-------+---------+-------------+
| 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)
发布于 2012-12-27 11:06:24
查询本身是如此简单,以至于我认为您不可能通过修改它来使它更快。不过,我还是想知道使用"IsNull(grouptag_id,0) = 0“是否会产生任何不同。我对此表示怀疑,但看看它是否刮掉任何东西可能会很有趣。
我认为真正的问题是,可能有很多记录的own_domain_id值为4,而where子句中的其他字段没有索引。您可以为它们创建单独的索引和/或如果您想要创建一个专门针对此查询的索引,那么就创建一个在引用的所有4个字段上键的索引。
其他一些意见:
如果有可能更改代码来处理空值(也许只是将它们当作0),那么您可以去掉在大多数这些字段中放置的默认值,并将它们改为空值。如果不是很多字段的值实际上大于0,那么如果许多字段设置为0,则会导致表占用磁盘上占用的空间更少,这将导致扫描表的时间更短。
您还可以对表进行水平或垂直分区。
水平:您可以将所有的top1字段放到一个top1表、所有的top3字段中,并将它们放在top3表中等等。或者,您可以在一个表中完成所有的雅虎,在另一个表中执行所有的bing;或者在一个表中执行所有的计数字段,在另一个表中执行所有的搜索字段。如果您发现自己通常一次只需要一组字段,那么这将减少搜索时间,但是如果您通常在大多数查询中获取所有字段,那么这当然不会有什么帮助。
垂直方向:这一项的工作量可能远远超过了它的价值,但您可以将表中的记录拆分到多个表中,并将它们放在多个硬盘上,同时异步地对它们进行查询。我一直在想谷歌是否做了类似的事情。
我还注意到,您正在为您的id使用bigint,它是8个字节,而不是仅为4个字节的int。如果你认为你会在某一时刻处理数以十亿计的记录,那么bigint显然是可行的,但否则你可以将你的数据库缩小约100兆,这也会使你的搜索速度稍微快一些。如果有必要的话,你没有理由现在就不能把它变成int,然后再把它变回bigint。
发布于 2012-12-27 11:12:39
正如Brandon Moore所说
查询本身是如此简单,以至于我认为您不可能通过修改它来使它更快。
不过,你可以试试这个,看看它是否有一点不同。
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;
https://stackoverflow.com/questions/14053345
复制相似问题