SQL несколько строк в виде столбцов (оптимизация)
У меня есть запрос SQL, который дает правильный результат, но выполняет слишком медленно.
Запрос работает по следующим трем таблицам:
customers
содержит много данных клиента, таких как имя, адрес, телефон и т. д. Для упрощения таблицы я использую только имя.
customdatas
содержит определенные пользовательские (не клиентские) данные. (Таблицы создаются программно, поэтому форма множественного числа не подходит для этой таблицы)
customercustomdatarels
связывает пользовательские данные с клиентом.
клиенты
Id Name (many more columns)
-----------------------------------------------------------------------
8053c6f4c5c5c631054ddb13d9186117 MyCustomer ...
2efd2aa5711ddfade1f829b12dd88cf3 CheeseFactory ...
CustomData
id key
-------------------------------------------------
22deb172c1af6e8e245634a751871564 favoritsport
86eea84d296df9309ad6ff36fd7f856e favoritcheese
customercustomdatarels (связь между клиентом и пользовательскими данными - с соответствующим значением)
customer customdata value
-------------------------------------------------------------------------------------
8053c6f4c5c5c631054ddb13d9186117 22deb172c1af6e8e245634a751871564 cycling
8053c6f4c5c5c631054ddb13d9186117 86eea84d296df9309ad6ff36fd7f856e cheddar
2efd2aa5711ddfade1f829b12dd88cf3 22deb172c1af6e8e245634a751871564 football
2efd2aa5711ddfade1f829b12dd88cf3 86eea84d296df9309ad6ff36fd7f856e mouldy
То, что я хочу, это таблица, в основном состоящая из всех данных вcustomers
с переменным количеством дополнительных столбцов, соответствующих пользовательским данным, указанным вcustomercustomdatarels
, Эти столбцы должны быть где-то определены, и поэтому я создал следующую таблицу, которая определяет такие дополнительные столбцы и сопоставляет их с ключом вcustomdata
Таблица:
test_customkeymapping
colkey customkey
---------------------
1 favoritsport
2 favoritcheese
Результат должен быть:
Name ExtraColumn_1 ExtraColumn_2
---------------------------------------------
CheeseFactory football mouldy
MyCustomer cycling cheddar
(ExtraColumn_1 поэтому является синонимом любимого вида спорта иExtraColumn_2 является синонимом сыра фаворита клиентов.)
Этот результат достигается путем выполнения следующего запроса:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('MAX(CASE
WHEN ckm.colkey = ', colkey, ' THEN
(SELECT value FROM customercustomdatarels ccdr2
LEFT JOIN customdatas cd2
ON cd2.id = ccdr2.customdata
WHERE cd2.key = ckm.customkey AND c.Id = ccdr2.customer)
END) AS ', CONCAT('`ExtraColumn_', colkey, '`'))
) INTO @sql
FROM test_customkeymapping;
SET @sql = CONCAT('SELECT c.Name, ', @sql, '
FROM customers c
LEFT JOIN customercustomdatarels ccdr
ON c.Id = ccdr.customer
LEFT JOIN customdatas cd
ON cd.Id = ccdr.customdata
LEFT JOIN test_customkeymapping ckm
ON cd.key = ckm.customkey
GROUP BY c.Id');
PREPARE stmt FROM @sql;
EXECUTE stmt;
Это работает. Но это слишком медленно (для 7000 клиентов это занимает ~ 10 секунд). На запрос большое влияние оказало решение этого вопроса:MySQL объединяет несколько строк в виде столбцов
Как мне оптимизировать этот запрос?