如何加快我的SQL查询?

时间:2012-09-22 19:04:41

标签: mysql 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天,以及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,并且在给定的纬度/经度对中,然后总计每个的计数。

我对这些东西愚蠢,所以如果我做一些愚蠢的话,请纠正我。谢谢你们!

1 个答案:

答案 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做了什么,但也尝试重构它,以便列值不是计算的一部分。