簡體   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