Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Ajuda do MySQL:Otimize a consulta de atualização que define a classificação de acordo com a ordem de outra coluna


Primeiro, eu mudaria o budget , cost e rank_score em inteiro ou outro tipo de dados numérico e em vez de
UPDATE table_name
SET rank_score = CONCAT(cost, budget) ;

Então você usaria:
UPDATE table_name
SET rank_score = cost * 1000 + budget * 1  ;

É mais fácil, pois você não terá que lidar com funções de string e ter algo como:
SELECT * 
FROM table_name
WHERE (conditions...)
ORDER BY rank_score DESC

(Parênteses:ter um parâmetro (1000 ) definido tão mais alto que o outro (1 ) é equivalente a ter um pedido de cost, budget . Tente isso para verificar:
SELECT * 
FROM table_name
ORDER BY cost DESC
       , budget DESC

Então, você pode descartar o rank_score tudo junto, a menos que você planeje fazer experimentos com vários valores de parâmetros.

Como outros apontaram, não é uma prática recomendada ter um campo que não armazene dados, mas um cálculo. É a desnormalização. Instalado, você mantém a tabela normalizada e deixa o banco de dados fazer os cálculos sempre que precisar:
SELECT id, budget, cost, 
       cost*1000 + budget*1 AS rank_score_calculated
FROM table_name
ORDER BY rank_score_calculated DESC

rank_score_calculated não é armazenado no exemplo acima. Dessa forma, você não precisará atualizar o campo calculado toda vez que um orçamento ou um custo for alterado ou uma nova linha for adicionada à tabela.

Há apenas uma desvantagem. Se a tabela for muito grande e você precisar que a consulta (e o cálculo) seja feita por muitos usuários e com muita frequência, e a tabela for atualizada com bastante frequência, isso pode tornar seu banco de dados lento. Nesse caso, deve-se começar a pensar em adicionar tal campo.

O outro caso é quando se precisa de um rank absoluto em todas as linhas da tabela, como sua necessidade. Como o MySQL não possui funções de "janela", é muito difícil escrever tal consulta em SQL puro.)

A classificação pode ser calculada usando variáveis ​​do MySQL
SELECT *
     , @rownum:[email protected]+1 AS rank_calculated
FROM table_name
   , (SELECT @rownum:=0) AS st
ORDER BY rank_score DESC

E se você quiser colocar esses valores em rank , usar:
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 ;

As duas consultas acima não são SQL puro. Você pode examinar a opção de mudar para outro sistema de banco de dados que suporte funções de janela, como Postgres, SQL-Server ou Oracle.