sql >> Base de Datos >  >> RDS >> Mysql

Ayuda de MySQL:optimizar la consulta de actualización que establece el rango según el orden de otra columna

Primero, cambiaría budget , cost y rank_score en entero u otro tipo de dato numérico y en lugar de

UPDATE table_name
SET rank_score = CONCAT(cost, budget) ;

Entonces usarías:

UPDATE table_name
SET rank_score = cost * 1000 + budget * 1  ;

Entonces es más fácil ya que no tendrá que lidiar con funciones de cadena y tener algo como:

SELECT * 
FROM table_name
WHERE (conditions...)
ORDER BY rank_score DESC

(Paréntesis:tener un parámetro (1000 ) establecido tan alto como el otro (1 ) es equivalente a tener una orden de cost, budget . Prueba esto para comprobar:

SELECT * 
FROM table_name
ORDER BY cost DESC
       , budget DESC

Entonces, puedes dejar caer el rank_score en total, a menos que, por supuesto, planee hacer experimentos con varios valores de parámetros.

Como han señalado otros, no es una buena práctica tener un campo que no almacene datos sino un cálculo. Es la desnormalización. Instaed, mantenga la tabla normalizada y deje que la base de datos haga los cálculos cada vez que lo necesite:

SELECT id, budget, cost, 
       cost*1000 + budget*1 AS rank_score_calculated
FROM table_name
ORDER BY rank_score_calculated DESC

rank_score_calculated no se almacena en el ejemplo anterior. De esta manera, no tendrá que actualizar el campo calculado cada vez que se cambie un presupuesto o un costo o se agregue una nueva fila en la tabla.

Solo hay un inconveniente. Si la tabla es realmente grande y necesita esa consulta (y el cálculo) realizada por muchos usuarios y muy a menudo, y la tabla se actualiza con bastante frecuencia, entonces puede ralentizar su base de datos. En ese caso, uno debería comenzar a pensar en agregar dicho campo.

El otro caso es cuando se necesita un rank absoluto en todas las filas de la tabla, como su necesidad. Debido a que MySQL no tiene funciones de "ventana", es muy difícil escribir una consulta de este tipo en SQL puro).

El rango se puede calcular usando variables de MySQL

SELECT *
     , @rownum:[email protected]+1 AS rank_calculated
FROM table_name
   , (SELECT @rownum:=0) AS st
ORDER BY rank_score DESC

Y si desea poner esos valores en rank , usa:

UPDATE table_name
         JOIN
         ( SELECT id
                , @rownum:[email protected]+1 AS rank_calculated
           FROM table_name
              , (SELECT @rownum:=0) AS st
           ORDER BY rank_score DESC
         ) AS r
         ON r.id = table_name.id
SET table_name.rank = r.rank_calculated ;

Las dos consultas anteriores no son SQL puro. Puede examinar la opción de pasar a otro sistema de base de datos que admita funciones de ventana, como Postgres, SQL-Server u Oracle.