Problemas de rendimiento con tabla derivada en SQL
-
24-10-2019 - |
Pregunta
Tengo problemas para usar una mesa derivada en MySQL. ¿El uso de una tabla derivada ralentiza inherentemente el procesamiento de una consulta?
Aquí está la consulta que estoy tratando de ejecutar. No se ejecutará y justo al tiempo.
Tiene éxito. Realmente, he aislado el problema para la última unión. Cuando saco la última unión funciona bien. Pero cuando agrego la última unión, se niega a ejecutar.
SELECT cr.COMMUNICATIONS_ID AS ANSWER_ID,
cr.CONSUMER_ID as VIEWER_ID,
cr.ACTION_LOG_ID,
nc.PARENT_COMMUNICATIONS_ID AS QUESTION_ID,
nc.SENDER_CONSUMER_ID AS REPLIER_ID,
ces.EXPERT_SCORE AS REPLIER_EXPERTISE,
cim.CONSUMER_INTEREST_EXPERT_ID AS DOMAIN
FROM (SELECT 234 AS CONSUMER_ID,
ACTION_LOG_ID,
COMMUNICATIONS_ID
FROM consumer_action_log
WHERE COMM_TYPE_ID=4) AS cr
JOIN network_communications AS nc ON
cr.COMMUNICATIONS_ID=nc.COMMUNICATIONS_ID
JOIN communication_interest_mapping AS cim ON
nc.PARENT_COMMUNICATIONS_ID=cim.COMMUNICATION_ID
JOIN consumer_expert_score AS ces ON
nc.SENDER_CONSUMER_ID=ces.CONSUMER_ID
AND cim.CONSUMER_INTEREST_EXPERT_ID=ces.CONSUMER_EXPERT_ID;
Solución
Espero que esto ayude ... aquí hay algunas declaraciones de índice de creación mysql. Básicamente, si puede agregar índices, asegúrese de que haya un índice que cubra cada una de sus columnas que conectan 2 o más tablas.
CREATE INDEX idx_nc
ON network_communications(COMMUNICATIONS_ID);
CREATE INDEX idx_cim
ON communication_interest_mapping(COMMUNICATION_ID);
CREATE INDEX idx_ces
ON consumer_expert_score(CONSUMER_ID, CONSUMER_EXPERT_ID);
Las tablas derivadas no son inherentemente malas, pero en este caso (ver más abajo) está extrayendo todos los registros de Consumer_Action_log que tienen un Comm_Type_id de 4. No parece haber una conexión a las otras tablas. Esa podría ser la causa de que el SQL nunca regrese.
SELECT cr.COMMUNICATIONS_ID,
cr.CONSUMER_ID,
cr.ACTION_LOG_ID,
nc.PARENT_COMMUNICATIONS_ID,
nc.SENDER_CONSUMER_ID,
ces.EXPERT_SCORE,
cim.CONSUMER_INTEREST_EXPERT_ID
FROM (SELECT 234 AS CONSUMER_ID,
ACTION_LOG_ID,
COMMUNICATIONS_ID
FROM consumer_action_log
WHERE COMM_TYPE_ID=4) AS cr
JOIN network_communications AS nc ON
cr.COMMUNICATIONS_ID=nc.COMMUNICATIONS_ID
JOIN communication_interest_mapping AS cim ON
nc.PARENT_COMMUNICATIONS_ID=cim.COMMUNICATION_ID
JOIN consumer_expert_score AS ces ON
nc.SENDER_CONSUMER_ID=ces.CONSUMER_ID
AND cim.CONSUMER_INTEREST_EXPERT_ID=ces.CONSUMER_EXPERT_ID;
Otros consejos
Además de los índices que deberían existir en sus tablas de búsqueda como se señala en Anser por John, me aseguraría de tener un índice en Comm_Type_ID en su tabla Consumer_Action_Log también.
Luego, agregue una palabra clave a su cláusula ... Siempre he visto excelentes resultados cuando una consulta está bien organizada en lugar de confiar en el motor de consulta para Optimze ...ver otra muestra aquí
SELECT STRAIGHT_JOIN
cr.COMMUNICATIONS_ID AS ANSWER_ID,
cr.CONSUMER_ID as VIEWER_ID,
etc... rest of your query...
Podría ser que el optimizador esté tratando de mirar otras tablas para descubrir qué obtener. Vea los comentarios en otra respuesta de StackOverflow a la que proporcioné el enlace.