简体   繁体   English

如何加快我的SQL查询?

[英]How can I speed up my SQL query?

Here is the query: 这是查询:

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`

It essentially finds any rows where the day of year is plus or minus 14 of today's day, and rows that the latlng spatial column is in the rectangle. 它基本上可以找到任何行,其中一年中的某一天是今天的正负14,以及latlng空间列在矩形中的行。

Here is what my database looks like: 这是我的数据库的样子:

#   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

There are 7 million records and the query is taking about 7 seconds. 有700万条记录,查询大约需要7秒钟。 I have no clue how to speed this up, thanks in advance! 我不知道如何提高速度,提前谢谢!

EXPLAIN: 说明:

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

UPDATED explanation of query: I believe MBRCONTAINS creates a rectangle where I can compare whether the latlng spatial point is inside or not. 更新的查询说明:我相信MBRCONTAINS创建一个矩形,我可以比较latlng空间点是否在内部。 The date part is finding dayofyear + or - 14 days. 日期部分是找到dayofyear +或 - 14天。 It is using modular arithmetic so that it won't mess up around the new years. 它使用模块化算法,因此它不会在新的一年里搞乱。 I had to put the MBRCONTAINS part in twice because of the use of OR. 由于使用了OR,我不得不将MBRCONTAINS部分放入两次。

My needs of the query are to find find all name s that have a day of the year + or - 14 days, and are within the given lat/long pairs, and then total the counts for each. 我对查询的需求是查找找到一年中某天+或 - 14天的所有name ,并且在给定的纬度/长度对中,然后总计每个的计数。

I'm dumb at this stuff so please correct me if I'm doing something dumb. 我对这些东西很愚蠢,所以如果我做一些愚蠢的话,请纠正我。 Thanks guys! 多谢你们!

Rewrite it so that your calculations happen once per query , rather than once per row by expressing your predicates such that the column is not part of the calculation. 重写它,以便您的计算每次查询一次,而不是每一次,通过表达您的谓词,使列不是计算的一部分。

For example, this expression: 例如,这个表达式:

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

which requires 7 millions calculations on date , can be expressed as 这就要求在700万个计算date ,可以表示为

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

which requires only 1 calculation and further would allow an index on the date column to be used. 这只需要1次计算,并且还允许使用date列上的索引。
That change alone will speed up your query. 仅这一改变将加快您的查询速度。

if you don't have an index on date, put one and your query will fly: 如果您没有日期索引,请输入一个,您的查询将会飞:

create index mytable_date on mytable(`date`);


I don't know what MBRCONTAINS does, but try to refactor it too so that the column value is not part of the calculation. 我不知道MBRCONTAINS做了什么,但也尝试重构它,以便列值不是计算的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM