sql >> Database >  >> RDS >> Mysql

MySQL Help:Updatequery optimaliseren die de rangorde instelt volgens de volgorde van een andere kolom

Ten eerste zou ik budget veranderen , cost en rank_score in integer of ander numeriek datatype en in plaats van

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

Dan zou je gebruiken:

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

Het is dan gemakkelijker omdat je niet met stringfuncties te maken hebt en iets hebt als:

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

(Haakjes:één parameter hebben (1000 ) zo hoger ingesteld dan de andere (1 ) is gelijk aan het hebben van een bestelling van cost, budget . Probeer dit om te controleren:

SELECT * 
FROM table_name
ORDER BY cost DESC
       , budget DESC

Je kunt dus heel goed de rank_score . laten vallen alles bij elkaar, tenzij je natuurlijk van plan bent experimenten te doen met verschillende parameterwaarden.

Zoals anderen al hebben opgemerkt, is het geen goede gewoonte om een ​​veld te hebben waarin geen gegevens maar een berekening worden opgeslagen. Het is de-normalisatie. In plaats daarvan houdt u de tabel genormaliseerd en laat u de database de berekeningen doen elke keer dat u deze nodig heeft:

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

rank_score_calculated wordt niet opgeslagen in het bovenstaande voorbeeld. Op deze manier hoeft u het berekende veld niet elke keer bij te werken wanneer een budget of een kostenpost wordt gewijzigd of een nieuwe rij wordt toegevoegd in de tabel.

Er is alleen een nadeel. Als de tabel erg groot is en je die zoekopdracht (en de berekening) door veel gebruikers en heel vaak nodig hebt, en de tabel wordt vaak bijgewerkt, dan kan het je database vertragen. In dat geval zou men moeten nadenken over het toevoegen van zo'n veld.

Het andere geval is wanneer men een absolute rank nodig heeft over alle tabelrijen, zoals uw behoefte. Omdat MySQL geen "venster"-functies heeft, is het erg moeilijk om zo'n query in pure SQL te schrijven.)

De rangorde kan worden berekend met behulp van MySQL-variabelen

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

En als u die waarden in rank wilt plaatsen , gebruik:

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 ;

De bovenstaande twee query's zijn geen pure SQL. U kunt de optie onderzoeken om naar een ander databasesysteem te gaan dat vensterfuncties ondersteunt, zoals Postgres, SQL-Server of Oracle.



  1. Hoe kan ik gegevens in SQL Server invoegen met VBNet

  2. Monitor SQL Database via SP_WhoIsActive of FogLight | Problemen met SQL Server-prestaties oplossen -1

  3. Is het sneller om MySQL te verbinden/gebruiken op localhost in plaats van op een domein (zelfs als het domein naar dezelfde computer wordt omgezet)?

  4. MySQL Enum prestatievoordeel?