sql >> Databáze >  >> RDS >> Mysql

Optimalizace dotazů MySQL pomocí těžkých spojení

Vaše data jsou špatně seskupená .

InnoDB bude ukládat řádky s "blízkými" PK fyzicky blízko sebe. Protože vaše podřízené tabulky používají náhradní PK, budou jejich řádky uloženy náhodně. Když přijde čas provést výpočty pro daný řádek v "hlavní" tabulce, musí DBMS přeskakovat všude, aby shromáždil související řádky z podřízených tabulek.

Místo náhradních klíčů zkuste použít „přirozenější“ klíče s rodičovským PK na přední hraně, podobně jako toto:

score_adjustments:
    entry_id: INT(11), FOREIGN KEY (entries.id)
    created: DATETIME
    amount: INT(4)
    PRIMARY KEY (entry_id, created)

rating_adjustments:
    entry_id: INT(11), FOREIGN KEY (entries.id)
    rating_no: INT(11)
    rating: DOUBLE
    PRIMARY KEY (entry_id, rating_no)

POZNÁMKA:Toto předpokládá created Rozlišení je dostatečně dobré a rating_no bylo přidáno, aby bylo možné více hodnocení na entry_id . Toto je jen příklad – PK můžete měnit podle svých potřeb.

Tím se "vynutí" řádky patřící stejnému entry_id být uloženy fyzicky blízko u sebe, takže SUM nebo AVG lze vypočítat pouhým skenováním rozsahu na klíči PK/clustering a s velmi malým počtem I/O.

Případně (např. pokud používáte MyISAM, který nepodporuje shlukování), obálka dotaz s indexy, takže podřízené tabulky se během dotazování vůbec nedotknou.

Kromě toho můžete denormalizovat svůj návrh a uložit aktuální výsledky do mezipaměti v nadřazené tabulce:

  • Uložte SUM(score_adjustments.amount) jako fyzické pole a upravte jej pomocí spouštěčů při každém vložení, aktualizaci nebo odstranění řádku z score_adjustments .
  • Uložte SUM(rating_adjustments.rating) jako "S" a COUNT(rating_adjustments.rating) jako "C". Když je přidán řádek do rating_adjustments , přidejte jej k S a zvyšte C. Vypočítejte S/C za běhu, abyste získali průměr. S aktualizacemi a mazáním zacházejte podobně.


  1. Zjistěte, zda byl řádek aktualizován nebo vložen

  2. Jak zvýšit výjimku v PL/SQL?

  3. Jak omezit slova, ale ne definice pomocí mysql

  4. Django admin MySQL pomalý INNER JOIN