我有一个复杂的查询,虽然相对较快的基于距离的排名查询(~0.6秒)还不够快。需要为美国的每个邮政编码运行查询,这导致总运行时间约为6小时40分钟。无论如何,这可以优化吗?
SELECT mt.*,
da.dealPrice,
da.dealSavings,
da.dealOriginalPrice,
da.dealDiscountPercent FROM
( SELECT businessType,title,rank,createDate,address1,city,STATE,ZIP,deal_ID,dealSaving FROM
( SELECT IF(@businessType=businessType,@ctr:=@ctr+1,@ctr:=1) AS RowNum, @businessType:=businessType AS businessType,title,rank,createDate,address1,city,STATE,ZIP,deal_ID,dealSaving
FROM
( SELECT deal_ID,title,distance,userProvider_ID,age_rank,createDate,address1,city,STATE,ZIP,dealSaving, age_rank * EXP(-POWER(GREATEST(distance-distance_scale,0),2)/((-2*POWER(distance_scale,2))/(2*LOG(distance_decay)))) AS rank, age,businessType
FROM
(SELECT sd.deal_ID,sd.dealURL,TRIM(sd.dealSaving) AS dealSaving,TRIM(sd.title) AS title,sd.userProvider_ID,p.radius,distance_scale,distance_decay,d.createDate, p.distance_unit*DEGREES(ACOS(COS(RADIANS(p.latpoint))*COS(RADIANS(sd.storeLat))*COS(RADIANS(p.longpoint - sd.storeLon))+SIN(RADIANS(p.latpoint))*SIN(RADIANS(sd.storeLat)))) AS distance, EXP(-POWER(GREATEST(DATEDIFF(CURDATE(),d.createDate)-SCALE,0),2)/((-2*POWER(SCALE,2))/(2*LOG(decay)))) AS age_rank,sd.businessType,sd.store_ID, DATEDIFF(CURDATE(),d.createDate) AS age,sd.address1,sd.city,sd.STATE,sd.ZIP
FROM search_deals sd
LEFT JOIN deals d ON sd.deal_ID = d.dealID
JOIN
( SELECT 40.6812509 AS latpoint,-73.9809685 AS longpoint,50.0 AS radius,69.0 AS distance_unit,5 AS SCALE,0.5 AS decay, 1 AS distance_scale, 0.001 AS distance_decay ) AS p ON 1=1
WHERE sd.storeLat BETWEEN p.latpoint - (p.radius / p.distance_unit) AND p.latpoint + (p.radius / p.distance_unit)
AND sd.storeLon BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint)))) AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND d.createDate >= DATE_ADD(CURDATE(),INTERVAL -90 DAY)
AND sd.flag = 0
AND sd.STATE = 'NY'
AND sd.userProvider_ID > 0
AND sd.businessType IN (1,2,3)
GROUP BY store_ID ) AS d
WHERE distance <= radius
ORDER BY rank DESC ) main
JOIN
(SELECT @ctr:=1) AS a
ORDER BY businessType, rank DESC) AS b
WHERE RowNum <= 5) mt
LEFT JOIN deals_addon da ON mt.deal_ID = da.deal_ID;
为查询运行说明会产生以下结果:
+------+-------------+------------+-------------+-----------------------------------------------------------------------------+------------+---------+---------------------------+-------+------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+------------+-------------+-----------------------------------------------------------------------------+------------+---------+---------------------------+-------+------------------------------------------+
| 1 | SIMPLE | <derived2> | ALL | NULL | NULL | NULL | NULL | 14136 | |
| 1 | SIMPLE | da | ref | deal_ID | deal_ID | 9 | mt.deal_ID | 1 | Using where |
| 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 14136 | Using where |
| 3 | DERIVED | <derived7> | system | NULL | NULL | NULL | NULL | 1 | Using filesort |
| 3 | DERIVED | <derived5> | ALL | NULL | NULL | NULL | NULL | 14136 | Using where |
| 7 | DERIVED | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
| 5 | DERIVED | <derived6> | system | NULL | NULL | NULL | NULL | 1 | Using temporary; Using filesort |
| 5 | DERIVED | sd | index_merge | search_lat_long,search_deal_ID,flag,state,userProvider_ID,drupal_1,drupal_2 | state,flag | 5,1 | NULL | 18848 | Using intersect(state,flag); Using where |
| 5 | DERIVED | d | eq_ref | PRIMARY,idx_createDate,createDate | PRIMARY | 8 | tb2099_9pprod.sd.deal_ID | 1 | Using where |
| 6 | DERIVED | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+------+-------------+------------+-------------+-----------------------------------------------------------------------------+------------+---------+---------------------------+-------+------------------------------------------+