以下是查询:
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天,以及latlng空间列在矩形中的行。
以下是我的数据库:
# 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创建一个矩形,我可以比较latlng空间点是否在内部。日期部分是找到dayofyear +或 - 14天。它使用模块化算术,因此它不会在新的一年里陷入困境。由于使用了OR,我不得不将MBRCONTAINS部分放入两次。
我对查询的需求是查找找到一年中某天+或 - 14天的所有name
,并且在给定的纬度/经度对中,然后总计每个的计数。
我对这些东西愚蠢,所以如果我做一些愚蠢的话,请纠正我。谢谢你们!
答案 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
做了什么,但也尝试重构它,以便列值不是计算的一部分。