2014-11-20 45 views
0

我有一個大表,有670k行,我正在運行一個SELECT,有很多WHERE來搜索和過濾有用的結果,有時候有沒有結果所選的過濾器和查詢只是遍佈整個表並花費大量時間,如果在30秒內找不到任何結果,我想停止查詢。MySQL當沒有足夠的結果時,按時間限制查詢

這是我的查詢:

SELECT date, s.name, l.id, l.title,ratingsum,numvotes,keyword,tag 
from news_links l 
LEFT JOIN sources s on s.id = l.source 
WHERE 
    l.date BETWEEN STR_TO_DATE(?,'%Y-%m-%d') 
    AND STR_TO_DATE(?,'%Y-%m-%d') 
    AND s.name like ? 
    AND ((numvotes-1) *?) <= l.ratingsum 
    AND numvotes > ? 
    AND matches = 1 
    AND tag >= ? 
    AND tag <= ? 
    AND (l.title like ? or l.keyword like ?) 
    AND category >= ? 
    AND category <= ? 
order by date desc 
limit ?,15 

我試圖運行一個子查詢,而不是加入,但它並沒有加快查詢。

新聞臺(640K行) -----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | UNI | NULL | auto_increment | | link | varchar(450) | NO | PRI | NULL | | | date | datetime | NO | MUL | NULL | | | title | varchar(145) | NO | MUL | NULL | | | source | int(11) | NO | MUL | NULL | | | text | mediumtext | YES | | NULL | | | numvotes | int(3) | NO | MUL | 0 | | | ratingsum | int(3) | NO | | 0 | | | matches | int(1) | NO | | 0 | | | keyword | varchar(45) | YES | | NULL | | | tag | int(1) | NO | | 0 | | +-----------+--------------+------+-----+---------+----------------+

我的索引建立在日期,標題,來源,numvotes以及對鏈接的主鍵

回答

0

670K行應該在MySQL的運行速度非常快。你應該仔細看看你的指數。開始在news_links.sourcenews_links.matches加入組合HASH指數:

ALTER TABLE news_links ADD INDEX myIdx1 USING HASH (source, matches) 

是什麼EXPLAIN SELECT ...爲您提供了嗎?

之後,您可以嘗試通過在索引中包含更多信息來進一步提高性能(請注意,MySQL將僅使用每個表的一個索引)。添加BTREE指數:

ALTER TABLE news_links ADD INDEX myIdx2 USING BTREE (source, matches, `date`) 

BTREE將有利於範圍,查詢(例如,在它BETWEEN)。 HASH適合平等/不平等條件。如果您想用混合條件(範圍相同)對幾列進行索引,請使用BTREE

EXPLAIN SELECT ...現在提供給您什麼?

+0

那麼,事實證明擁有670k〜500KB的中文文本行是不好的,所以我將**文本**行移到了另一個表中,並在必要時添加了合適的連接,現在查詢運行時間短於6秒 – 2014-11-22 22:08:07