2015-11-06 2 views
0

У меня вопрос о радиусе zipcode. Нижеприведенный выбор имеет функцию радиуса, которую я нашел. Это нормально, но немного медленнее. Кроме того, есть ли способ вернуть расстояние до внешнего выбора? Я просто закодировал LONGITUDE и LATITUDE для удобства этого вопроса.MYSQL - радиус Zipcode - оптимальное и обратное расстояние до внешнего выбора

Заранее спасибо. Фил

     SELECT 
          A.MEMBER_ID                                                      
         FROM MEMBER A,                       
          DETAILS B,                        
          ZIPCODE D 
         WHERE A.ZIPCODE_CODE IN (Select resultzip.ZIPCODE from               
           (SELECT                           
            pos.ZIPCODE,                         
            3958 * 2 * ASIN(SQRT(POWER(SIN((39.946438 - abs(pos.LATITUDE)) * pi()/180/2),2) +   
            COS(39.946438 * pi()/180) * COS(abs(pos.LATITUDE) * pi()/180) * POWER(SIN((-74.915955 - pos.LONGITUDE) * 
            pi()/180/2), 2))) AS distance_return_this_to_outer_select                   
           FROM ZIPCODE pos                       
           HAVING distance_return_this_to_outer_select < 100                   
           ORDER BY distance_return_this_to_outer_select)                        
           AS resultzip)                                            
          AND A.ZIPCODE_CODE = D.ZIPCODE                 
          AND A.MEMBER_ID = B.MEMBER_ID         
          Limit 0,15; 
+0

Одна из идей заключалась бы в том, чтобы найти или создать правильный UDF, но если компиляция кода не ваша вещь (это определенно не моя), тогда вы можете построить sproc. Это будет не намного быстрее, но это будет намного более элегантно. Затем взгляните на EXPLAIN для этого запроса, чтобы узнать, какие индексы будут наиболее эффективными. – Strawberry

+0

Кроме того, я подозреваю, что запрос MySQL умножить константы на 2 или разделить их на 180 немного меньше эффективности, чем просто сказать, что это значения – Strawberry

+0

Спасибо для вашего комментария. Я посмотрю на UDF – philipfwilson

ответ

0

Я просто написал функцию расстояния, часть большого UDF работает в 150ns на процессоре AMD A10-6800K 2ГГц. Вы можете создать UDF обертки вокруг него (смотреть на SQL/udf_example.c в источнике данных MySQL, поиск myfunc_double):

#define R_EARTH_MILES 3963.1676 
static inline double deg2rad(double deg) { 
    return (deg * M_PI/180); 
} 

static inline double rad2deg(double rad) { 
    return (rad * 180/M_PI); 
} 


    static inline double earth_distance(double lat1, double lon1, double lat2, double lon2) 
    { 
     double dlat = deg2rad(lat2 - lat1), dlon = deg2rad(lon2 - lon1); 
     double central_hs = (1.0 - cos(dlat))/2.0 + cos(deg2rad(lat1)) * cos(deg2rad(lat2)) * (1.0 - cos(dlon))/2.0; 
     double central_angle = 2 * atan2(sqrt(central_hs), sqrt(1 - central_hs)); 
     return R_EARTH_MILES * central_angle; 
    } 

Он использует метод гаверсинуса опирающийся на некоторых умных тригонометрических идентичностях для уменьшения чисел с плавающей точкой операции.

Update:

завернул в отдельную UDF, что вы должны быть в состоянии развернуть, следуя инструкциям в файле README.md:

http://github.com/spachev/mysql_udf_bundle

На втором думали ваши проблемы медленность, скорее всего, не связанные с вычислением, а скорее из изучения слишком большого количества строк для ответа на вопрос, потому что мы не можем использовать ключ для фильтрации.

Я бы рекомендовал хранить ваши координаты в типе GEOMETRY с помощью клавиши PROTITIAL, а затем использовать функцию CONTAINS() с квадратом с центром в вашей целевой точке и диаметром поиска в качестве стороны для фильтрации большинства точек и затем отфильтровывают остальное, используя метод земной дистанции.

+0

http://www.codeguru.com/cpp/data/mfc_database/misc/article.php/c12615/MySQL-UDFs.htm Я не создал UDF, и мой опыт C тоже немного ржавый. Каков самый быстрый способ сделать это? – philipfwilson

+0

Я закодировал его для вас (и кому бы он ни был полезен): https://github.com/spachev/mysql_udf_bundle –

+0

Спасибо Саше. Я посмотрю на это сегодня. – philipfwilson

Смежные вопросы