Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Pomoc MySQL:Zoptymalizuj zapytanie aktualizacyjne, które ustawia rangę zgodnie z kolejnością innej kolumny

Najpierw zmieniłbym budget , cost i rank_score na liczbę całkowitą lub inny numeryczny typ danych, a zamiast

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

Wtedy użyjesz:

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

Jest to łatwiejsze, ponieważ nie będziesz musiał zajmować się funkcjami łańcuchowymi i mieć coś takiego:

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

(Nawiasy:posiadanie jednego parametru (1000 ) ustawić tak wyżej niż inne (1 ) jest równoważne z zamówieniem cost, budget . Spróbuj to sprawdzić:

SELECT * 
FROM table_name
ORDER BY cost DESC
       , budget DESC

Możesz więc obniżyć rank_score w sumie, chyba że oczywiście planujesz eksperymentować z różnymi wartościami parametrów.

Jak zauważyli inni, nie jest najlepszą praktyką posiadanie pola, które przechowuje nie dane, ale obliczenia. To denormalizacja. Zamiast tego utrzymujesz normalizację tabeli i pozwalasz bazie danych wykonywać obliczenia za każdym razem, gdy tego potrzebujesz:

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

rank_score_calculated nie jest przechowywany w powyższym przykładzie. Dzięki temu nie będziesz musiał aktualizować pola obliczeniowego za każdym razem, gdy budżet lub koszt zostanie zmieniony lub dodany zostanie nowy wiersz w tabeli.

Jest tylko jedna wada. Jeśli tabela jest naprawdę duża i potrzebujesz tego zapytania (i obliczeń) wykonywanego przez wielu użytkowników i bardzo często, a tabela jest dość często aktualizowana, może to spowolnić twoją bazę danych. W takim przypadku należy zacząć myśleć o dodaniu takiego pola.

Inny przypadek to sytuacja, w której potrzebna jest bezwzględna rank we wszystkich rzędach tabeli, tak jak potrzebujesz. Ponieważ MySQL nie ma funkcji "okienkowych", bardzo trudno jest napisać takie zapytanie w czystym SQL.)

Rangę można obliczyć za pomocą zmiennych MySQL

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

A jeśli chcesz umieścić te wartości w rank , użyj:

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 ;

Powyższe dwa zapytania nie są czystym SQL. Możesz sprawdzić opcję przejścia do innego systemu baz danych, który obsługuje funkcje okien, takie jak Postgres, SQL-Server lub Oracle.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Priorytet operatora AND i OR w zapytaniu wybierającym Mysql

  2. Najlepszy sposób na przechowywanie wiadomości czatu w bazie danych?

  3. DOŁĄCZENIE LEWEJ MySQL?

  4. codeigniter nodejs i nowjs integracja

  5. dodanie 1 dnia do wartości formatu DATETIME