簡體   English   中英

MySQL查詢執行需要一個大表的時間?

[英]MySQL query execution takes time with a single large table?

我制作了一個抓取腳本,將某些網站的信息下載到數據庫中,該數據庫用於進一步監控歷史列表信息及其總計數。

這是表的結構:

    CREATE TABLE IF NOT EXISTS `biz_listing` (
          `id` bigint(11) NOT NULL,
          `lid` bigint(11) NOT NULL,
          `cid` bigint(11) NOT NULL,
          `name` varchar(300) NOT NULL,
          `type` enum('homeservices','restaurants') NOT NULL,
          `location` varchar(300) NOT NULL,
          `businessID` varchar(300) NOT NULL,
          `reviewcount` int(6) NOT NULL,
          `rating` decimal(10,1) NOT NULL,
          `city` varchar(300) NOT NULL,
          `categories` varchar(300) NOT NULL,
          `result_month` varchar(10) NOT NULL,
          `updated_date` date NOT NULL,
          KEY `businessID` (`businessID`),
          KEY `updated_date` (`updated_date`)
        ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

到目前為止,該腳本已經收集了大約350萬個結果,但是由於表中的大量記錄,腳本在查詢執行中花費了大量時間並導致超時問題。我們有一些查詢根據結果進行報告填充。抓取腳本是實時的並且正在填充結果,但是目前我無法根據聚合函數生成報告。

作為參考,這是用於聚合報告的查詢:

SELECT 
COUNT(t.`type`) AS count,
COUNT(t.`businessID`) AS bizcount, 
SUM(t.reviewcount) AS reviewcount,
t.`type`,t.`location` as city 
FROM `biz_listing` t 
INNER JOIN ( SELECT `businessID`,count(*) c 
FROM `biz_listing` 
where 
DATE_FORMAT(`updated_date`, '%m %Y') 
BETWEEN '01 2014' AND '02 2014' 
group by `businessID` HAVING c = 2 ) t2 ON t2.`businessID` = t.`businessID` 
where DATE_FORMAT(t.`updated_date`, '%m %Y')= '01 2014' 
and t.type='homeservices' 
GROUP BY t.location, t.result_month

上述查詢用於獲取商家列表計數及其審核計數的位置明智報告。 此處列表顯示2014年1月和2014年2月在數據庫中常見的企業匯總報告。

現在,來自表biz_listing的查詢執行花費了很多時間,並且通常該過程失敗。

說明

在此輸入圖像描述

將所有數據存儲在一個表中的原因是什么? 當前腳本設置為繼續將信息抓取到同一個表本身。 我不能丟失任何數據,我也應該讓報告更快地進行查詢。

在某些論壇中,我發現表格大小在這種情況下不是問題,適當的分區會有所幫助。 由於我對數據感到擔心,我對制作實驗感到困惑和擔心。

由於表后面應該有更多的記錄,表的分區可以幫助我。 我只是從參考文檔中獲得了分區的想法,我對如何實現它感到困惑?

任何建議或建議都非常值得贊賞。如有必要,我還可以提供任何支持信息。

首先要做的是刪除DATE_FORMAT並檢查日期: -

SELECT 
    COUNT(t.`type`) AS count,
    COUNT(t.`businessID`) AS bizcount, 
    SUM(t.reviewcount) AS reviewcount,
    t.`type`,
    t.`location` as city 
FROM `biz_listing` t 
INNER JOIN 
( 
    SELECT `businessID`,count(*) c 
    FROM `biz_listing` 
    WHERE updated_date BETWEEN '2014/01/01' AND '2014/02/28' 
    GROUP BY `businessID` 
    HAVING c = 2 
) t2 ON t2.`businessID` = t.`businessID` 
WHERE updated_date BETWEEN '2014/01/01' AND '2014/02/28' 
AND t.type='homeservices' 
GROUP BY t.location, t.result_month

這方面的缺點是您必須指定該月的最后一天。 你可以使用LAST_DAY結束: -

SELECT 
    COUNT(t.`type`) AS count,
    COUNT(t.`businessID`) AS bizcount, 
    SUM(t.reviewcount) AS reviewcount,
    t.`type`,
    t.`location` as city 
FROM `biz_listing` t 
INNER JOIN 
( 
    SELECT `businessID`,count(*) c 
    FROM `biz_listing` 
    WHERE updated_date BETWEEN '2014/01/01' AND LAST_DAY('2014/02/01')
    GROUP BY `businessID` 
    HAVING c = 2 
) t2 ON t2.`businessID` = t.`businessID` 
WHERE updated_date BETWEEN '2014/01/01' AND LAST_DAY('2014/02/01')
AND t.type='homeservices' 
GROUP BY t.location, t.result_month

請注意,因為它在常量LAST_DAY上執行,所以在查詢中每次執行一次,而不是對它檢查的每一行執行一次。

您可能希望在表上添加覆蓋索引,並在表上添加update_date(即,一個索引具有兩個列)。 同樣,添加一個涵蓋businessID和update_date的索引。

編輯

再次查看您的查詢,看起來您正在尋找一個月的業務ID匹配,該記錄在該月和下個月有記錄。 如果我理解你想要的每個企業每個月只能有1條記錄(因此你計算它們超過2個月並使用HAVING ... = 2)。

如果這是正確的,那么你可以做多個連接,每個月一個: -

SELECT 
        COUNT(t0.type) AS count,
        COUNT(t0.businessID) AS bizcount, 
        SUM(t0.reviewcount) AS reviewcount,
        t0.type,
        t0.location as city ,
        t0.result_month
FROM biz_listing t0 
INNER JOIN biz_listing t1
ON t0.businessID = t1.businessID
INNER JOIN biz_listing t2
ON t0.businessID = t2.businessID
WHERE t0.updated_date BETWEEN '2014/01/01' AND LAST_DAY('2014/01/01')
AND t1.updated_date BETWEEN '2014/01/01' AND LAST_DAY('2014/01/01')
AND t2.updated_date BETWEEN '2014/02/01' AND LAST_DAY('2014/02/01')
AND t0.type='homeservices' 
GROUP BY t.location, t.type, t.result_month

請注意,如果我誤解了並且businessID每個月可以有多個記錄,那么這將無效。

請在updated_date上創建數據庫表的索引並type列,這將有助於快速執行查詢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM