2012-09-22 67 views
3

下面是該查詢:如何加快我的SQL查詢?

SELECT name, SUM( `count`) AS Total 
FROM `identdb` 
WHERE MBRCONTAINS(GEOMFROMTEXT( 'LineString(34.4 -119.9, 34.5 -119.8)') , latlng) 
AND MOD(DAYOFYEAR(CURDATE()) - DAYOFYEAR( `date`) +365, 365) <=14 
OR MOD(DAYOFYEAR( `date`) - DAYOFYEAR(CURDATE()) +365, 365) <=14 
AND MBRCONTAINS(GEOMFROMTEXT( 'LineString(34.4 -119.9, 34.5 -119.8)') , latlng) 
GROUP BY `name` 

它本質上發現的任何行,其中一年中的天爲正負今天白天到14,和行的經緯度空間列是矩形。

這裏是我的數據庫是什麼樣子:

# Column Type  Collation 
1 name varchar(66) utf8_general_ci 
2 count tinyint(3) 
3 date date  
4 latlng geometry 
5 lat1 varchar(15) latin1_swedish_ci 
6 long1 varchar(15) latin1_swedish_ci 

Keyname Type Unique Packed Column Cardinality Collation Null Comment 
PRIMARY BTREE Yes No name 0 A  
         count 0 A 
         date 0 A 
         lat1 0 A 
         long1 6976936 A 
sp_index SPATIAL No No latlng (32) 0 A 

有700萬次的記錄和查詢花費約7秒鐘。我不知道如何加快速度,提前感謝!

說明:

id select_type table type possible_keys key  key_len ref rows  Extra 
1 SIMPLE  identdb ALL  sp_index  NULL NULL NULL 6976936 Using where; Using temporary; Using filesort 

更新的查詢的解釋: 我相信MBRCONTAINS創建一個矩形,在那裏我可以比較的經緯度座標點是內部還是不行。日期部分是發現日期+或 - 14天。它正在使用模塊化算術,以便在新的一年中不會搞砸。由於使用OR,我不得不將MBRCONTAINS部分放入兩次。

我的查詢需求是找到所有name s有一年中的一天+或 - 14天,並且在給定的緯度/長度對內,然後總計每個的計數。

我很笨,所以請糾正我,如果我做一些愚蠢的事情。多謝你們!

+0

請附上查詢的說明計劃。 –

+0

爲什麼MBR包含位執行兩次?這是一個錯字嗎? –

+0

你知道如何解釋計劃嗎? –

回答

6

,而不是每個行曾經通過表達您的謂詞使得列不是計算的一部分重寫它,這樣你的計算每查詢發生一次。

例如,此表達式:

MOD(DAYOFYEAR(CURDATE()) - DAYOFYEAR( `date`) +365, 365) <= 14 

這需要對date 7次百萬的計算,可以表示爲

`date` between SUBDATE(CURDATE(), 14) and ADDDATE(CURDATE(), 14) 

僅需要1次計算,並進一步允許在date的索引要使用的列。
單獨的更改會加快您的查詢速度。

,如果你沒有對過期的指標,把一個和您的查詢就會飛:

create index mytable_date on mytable(`date`); 


我不知道是什麼MBRCONTAINS沒有,但嘗試重構它也使得列值不是計算的一部分。

+0

我做了你的改變,現在查詢花了35秒?我相信MBRCONTAINS會創建一個矩形來查看該點是否在該矩形內。 – Patrick

+0

+1,雖然你的表達不一致(但可能更接近OP的意圖)。 –

+0

@Patrick,你有'日期'列的索引嗎? –