В моей базе данных есть промежуточная таблица со следующей структурой:
CREATE TABLE featureMappings (
id bigint(20) NOT NULL AUTO_INCREMENT,
visitId bigint(20) NOT NULL,
featureId bigint(20) NOT NULL,
textValue text DEFAULT NULL,
hashTextValue char(32) GENERATED ALWAYS AS (MD5(textValue)) VIRTUAL,
PRIMARY KEY (id));
ALTER TABLE featureMappings
ADD INDEX fsHashTextValue (featureId, hashTextValue)
При обычном запуске эта таблица содержит приблизительно 40–100 миллионов строк.Существует много повторяющихся текстовых значений, поэтому я использую ключ hashTextValue, чтобы иметь возможность индексировать этот столбец.
Выполнение следующего запроса занимает около 25 секунд:
CREATE TEMPORARY TABLE temp AS
SELECT
featureId,
hashTextValue
FROM
featureMappings
GROUP BY featureId, hashTextValue
Вопрос
Я хочу извлечь значение в textValue
столбец рядом со столбцами featureId
и hashTextValue
.
Я пробовал два подхода.Оба этих фактора значительно увеличили время запроса, поэтому я ищу лучшее решение.
Замедленный вариант 1 - добавление textValue
к запросу
При выполнении изменения belo на запрос время обработки составляло от 25 секунд до 10 минут.,Я пытался гуглить, как получается textValue
, когда не используется агрегатная функция, но не смог найти четкого ответа.
CREATE TEMPORARY TABLE temp AS
SELECT
featureId,
hashTextValue,
textValue # I also tried MIN(textValue)
FROM
featureMappings
GROUP BY featureId, hashTextValue
Сложный вариант 2: итеративное обновление
Мой предпочтительный подход состоит в том, чтобы выполнять итерации по уникальным комбинациям первого запроса, а затем выполнять цикл по следующим запросам.:
SELECT featureId, hashTextValue INTO @fid, @htv
FROM temp
WHERE textValue is NULL and hashTextValue IS NOT NULL
LIMIT 1;
SELECT textValue
INTO @textValue
FROM featureMappings
WHERE featureId = @fid and hashTextValue = @htv
LIMIT 1;
UPDATE temp
SET textValue = @textValue
WHERE featureId = @fid AND hashTextValue = @htv;
Конфигурация сервера
Это выполняется на AWS RDS Aurora на основе Mysql 5.7.Сервер имеет ограниченную (2 ГБ) память и обычно имеет меньше свободной памяти, чем размер индекса в таблице.