2011-11-24 58 views
0

我有幾個表,包含(AO)以下字段:加入多個表使得查詢運行時間過長

tweets: 
-------------------------- 
tweet_id ticker created_at 
-------------------------- 
1  1  1298063318 
2  1  1298053197 

stocks: 
--------------------------------- 
ticker date  close volume 
--------------------------------- 
1  1313013600 12.25 40370600 
1  1312927200 11.60 37281300 

wiki: 
----------------------- 
ticker date  views 
----------------------- 
1  1296514800 550 
1  1296601200 504 

我想要編譯鳴叫,收盤,成交量和每天的訪問量排名的概述(對於由ticker = 1標識的行)。推文表格是領先的,這意味着如果有一個沒有推文的日期,那麼當天的收盤,交易量和觀點就不重要了。在oter的話,我想查詢的輸出是這樣的:

------------------------------------- 
date  tweets close volume views 
------------------------------------- 
2011-02-13 4533 12.25 40370600 550 
2011-02-14 6534 11.60 53543564 340 
2011-02-16 5333 13.10 56464333 664 

在這個例子中輸出,沒有微博上2011-02-15,所以沒有必要對數據的其餘部分那天。我的查詢到目前爲止:

SELECT 
    DATE_FORMAT(FROM_UNIXTIME(tweets.created_at), '%Y-%m-%d') AS date, 
    COUNT(tweets.tweet_id) AS tweets, 
    stocks.close, 
    stocks.volume, 
    wiki.views 
FROM tweets 
LEFT JOIN stocks ON tweets.ticker = stocks.ticker 
LEFT JOIN wiki ON tweets.ticker = wiki.ticker 
WHERE tweets.ticker = 1 
GROUP BY date 
ORDER BY date ASC 

有人可以驗證此查詢是否正確?它不會遇到任何錯誤,但會凍結我的電腦。也許我應該在這裏或那裏設置一個索引,可能在「ticker」列上?

[編輯]

按照要求,該表的定義:

CREATE TABLE `stocks` (
    `ticker` int(3) NOT NULL, 
    `date` int(10) NOT NULL, 
    `open` decimal(8,2) NOT NULL, 
    `high` decimal(8,2) NOT NULL, 
    `low` decimal(8,2) NOT NULL, 
    `close` decimal(8,2) NOT NULL, 
    `volume` int(8) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

CREATE TABLE `tweets` (
    `tweet_id` int(11) NOT NULL AUTO_INCREMENT, 
    `ticker` varchar(5) NOT NULL, 
    `id_str` varchar(18) NOT NULL, 
    `created_at` int(10) NOT NULL, 
    `from_user` int(11) NOT NULL, 
    `text` text NOT NULL, 
    PRIMARY KEY (`tweet_id`), 
    KEY `id_str` (`id_str`), 
    KEY `from_user` (`from_user`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

CREATE TABLE `wiki` (
    `ticker` int(3) NOT NULL, 
    `date` int(11) NOT NULL, 
    `views` int(6) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

我希望這有助於。

+0

你可以發佈表定義'SHOW CREATE TABLE ...'和'EXPLAIN SELECT ...'的輸出嗎? –

+0

查看編輯後的TS。我希望它可以幫助:-) – Pr0no

回答

1

相信你應該檢查表格之間的連接。您的查詢不會指出哪些股票 - 行(或維基行)將被匹配到推文的日期。根據示例數據,匹配所有股票和具有相同ticker_id的wiki行進行匹配。

股票和維基表在某一天的股票和維基表中只有一行嗎?假如是這樣的話,更合乎邏輯的查詢應該是這樣的:

SELECT 
    DATE_FORMAT(FROM_UNIXTIME(t.created_at), '%Y-%m-%d') AS date, 
    COUNT(t.tweet_id) AS tweets, 
    s.close, 
    s.volume, 
    w.views 
FROM tweets t 
    LEFT JOIN stocks s ON t.ticker = s.ticker 
     and FROM_UNIXTIME(t.created_at,'%Y-%m-%d')=FROM_UNIXTIME(s.date,'%Y-%m-%d') 
    LEFT JOIN wiki w ON t.ticker = w.ticker 
     and FROM_UNIXTIME(t.created_at,'%Y-%m-%d')=FROM_UNIXTIME(w.date,'%Y-%m-%d') 
WHERE tweets.ticker = 1 
GROUP BY date, s.close, s.volume, w.views 
ORDER BY date ASC 

如果有個股多行/維基某一天的一個股票,在你需要的聚合函數適用於那些列,以及將COUNT(t.tweet_id)更改爲COUNT(distinct t.created_at)。

2

你對指數是正確的,沒有股票指數,你將不得不在所有表格中進行何處搜索,如果它們很大,則需要花費大量時間。

我建議您至少每隔一段時間打開logging of all queries that run without index以查找如果不是已經很慢,則在數據增加時會很慢。

如果您發現它們很慢,請檢查[EXPLAIN SELECT ...][2],瞭解如何解釋結果(不容易但很重要),以瞭解放置新索引的位置。

1

我認爲,問題之一是日期計算

DATE_FORMAT(FROM_UNIXTIME(tweets.created_at), '%Y-%m-%d') date 

嘗試將此字段添加到鳴叫表,以避免CPU消耗

編輯: 你可以使用這樣的事情

CREATE TABLE `stocks` (
    `ticker` int(3) NOT NULL, 
    `date` int(10) NOT NULL, 
    `open` decimal(8,2) NOT NULL, 
    `high` decimal(8,2) NOT NULL, 
    `low` decimal(8,2) NOT NULL, 
    `close` decimal(8,2) NOT NULL, 
    `volume` int(8) NOT NULL, 
    `day_date` varchar(10) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

CREATE TABLE `tweets` (
    `tweet_id` int(11) NOT NULL AUTO_INCREMENT, 
    `ticker` varchar(5) NOT NULL, 
    `id_str` varchar(18) NOT NULL, 
    `created_at` int(10) NOT NULL, 
    `from_user` int(11) NOT NULL, 
    `text` text NOT NULL, 
    `day_date` varchar(10) NOT NULL, 
    PRIMARY KEY (`tweet_id`), 
    KEY `id_str` (`id_str`), 
    KEY `from_user` (`from_user`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

CREATE TABLE `wiki` (
    `ticker` int(3) NOT NULL, 
    `date` int(11) NOT NULL, 
    `views` int(6) NOT NULL, 
    `day_date` varchar(10) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 


SELECT 
tweets.day_date AS date, 
COUNT(tweets.tweet_id) AS tweets, 
stocks.close as close, 
stocks.volume as volume, 
wiki.views as views 
FROM tweets 
LEFT JOIN stocks ON tweets.ticker = stocks.ticker 
       and tweets.day_date = stocks.day_date 
LEFT JOIN wiki ON tweets.ticker = wiki.ticker 
       and tweets.day_date = wiki.day_date 
WHERE tweets.ticker = 1 
GROUP BY date, close, volume, views 
ORDER BY date ASC 
+0

這可以做一個查詢(我已經創建了一個額外的列,在tweets表中說「full_date」? – Pr0no