У меня есть хранимая процедура (предоставленная ниже), которую я написал для обработки около 25 миллионов записей. Эта эта хранимая процедура выполняет задание lat & lon, расстояние (25 миль) и количество записей для присвоения (12), найти все записи, находящиеся в данных границах на основе 25 миль, и назначить до 12 записей пользователю, у которого еще нет записей. И пользователь может иметь только одну запись для каждой категории (так что 12 записей с отдельной категорией).MySQL хранит proc - Обработка миллионов записей - как ускорить
Хранимая процедура отлично работает. Единственная проблема - это длиться долго. Я создаю 8 общих проков, каждый из которых идентичен, за исключением рабочей таблицы (POSTSINAREATBL [1-8]), поэтому я могу ускорить процесс. У меня были скрипты, работающие в течение 4 дней, и обработали только 3,5 миллиона из 25 миллионов записей.
Я надеюсь, что у кого-то может быть некоторое понимание и помощь в том, как ускорить это. Мне действительно нужно получить все записи, обработанные в течение следующих 1-2 дней, и по курсу, который он собирается сейчас, это займет почти месяц!
Кроме того, с 8 сценариями, у меня есть процессор, работающий на 99,8%, поэтому я на максимальной емкости.
DELIMITER $$
CREATE PROCEDURE `get_pins_in_boundaries`(IN mylon double, IN mylat double, IN dist int, IN numrecords int)
BEGIN
declare isDone INT;
declare lat float;
declare lng float;
declare lon1 float;
declare lon2 float;
declare lat1 float;
declare lat2 float;
declare this_iter_pin_id int;
declare use_this_user_id int;
DECLARE num_results_in_area int;
DECLARE cur_posts_to_assign_to_user CURSOR FOR select pin_id from POSTSINAREATBL group by category_id limit numrecords;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET isDone = 1;
IF mylon = 0.000000 OR mylat = 0.000000 THEN
SELECT CONCAT('complete') AS results;
ELSE
SET lat=mylon;
SET lng=mylat;
-- calculate lon and lat for the rectangle:
set lon1 = mylon-dist/abs(cos(radians(mylat))*69);
set lon2 = mylon+dist/abs(cos(radians(mylat))*69);
set lat1 = mylat-(dist/69); set lat2 = mylat+(dist/69);
-- calculate lon and lat for the rectangle:
set lon1 = lng - dist/ABS(COS(RADIANS(lat)) * 111.04);
set lon2 = lng + dist/ABS(COS(RADIANS(lat)) * 111.04);
set lat1 = lat - dist/(111.04);
set lat2 = lat + dist/(111.04);
-- create temp table and store records matching criteria into table
CREATE TABLE IF NOT EXISTS POSTSINAREATBL(
pin_id BIGINT NOT NULL,
category_id BIGINT NOT NULL,
distance DECIMAL(6,1)
);
INSERT INTO POSTSINAREATBL (
SELECT pin_id,category_id, (3959 * acos(cos(radians(lat)) * cos(radians(latitude)) * cos(radians(longitude) - radians(lng)) + sin(radians(lat)) * sin(radians(latitude)))) as distance
FROM skoovy_prd.pins
WHERE longitude between lon1 and lon2
and latitude between lat1 and lat2
and user_id =0
);
select count(*) INTO num_results_in_area from POSTSINAREATBL;
WHILE num_results_in_area > 0 DO
SET use_this_user_id = (SELECT user_id from skoovy_prd.users WHERE user_id NOT IN(select user_id from skoovy_prd.posts_users_processed) LIMIT 1);
INSERT INTO skoovy_prd.posts_users_processed (user_id) VALUES(use_this_user_id);
SET isDone = 0;
OPEN cur_posts_to_assign_to_user;
REPEAT
FETCH cur_posts_to_assign_to_user INTO this_iter_pin_id;
UPDATE skoovy_prd.pins SET pins.user_id = use_this_user_id WHERE pins.pin_id = this_iter_pin_id;
DELETE FROM POSTSINAREATBL WHERE pin_id = this_iter_pin_id;
SET num_results_in_area = num_results_in_area - 1;
UNTIL isDone END REPEAT;
CLOSE cur_posts_to_assign_to_user;
END WHILE;
TRUNCATE TABLE POSTSINAREATBL;
SELECT CONCAT('complete') AS results;
END IF;
END
Спасибо. Я запустил несколько тестов, и не кажется, что проблема «проблема» в запросе для данных в диапазонах геолокации. – kambythet
Если вы хотите найти узкое место вашей хранимой процедуры, запустите «объяснять» для каждого запроса в вашей процедуре. После того, как вы найдете проблему, просто оптимизируйте ее, используя индексы. http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html – xardas
Готово уже. Дело не в том, что отсутствуют индексы, индексы не используются должным образом и т. Д. Это то, что есть миллионы записей, и я пытаюсь понять, может быть, есть более эффективный способ сделать это и быстро выполнить действия, которые в настоящее время выполняет proc выполнения. – kambythet