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

Jak zrychlit select count(*) se skupinou podle a kde?

Zde je několik věcí, které bych zkusil v pořadí podle rostoucí obtížnosti:

(snadnější) - Ujistěte se, že máte správný index pokrytí

CREATE INDEX ix_temp ON relations (relation_title, object_title);

To by mělo maximalizovat výkon vzhledem k vašemu stávajícímu schématu, protože (pokud vaše verze optimalizátoru mySQL není opravdu hloupá!) to minimalizuje množství I/O potřebných k uspokojení vašeho dotazu (na rozdíl od toho, když je index v obráceném pořadí, kde je celý index musí být naskenován) a pokryje dotaz, takže se nebudete muset dotýkat seskupeného indexu.

(trochu těžší) – ujistěte se, že vaše pole varchar jsou co nejmenší

Jedním z problémů výkonu s varchar indexy na MySQL je to, že při zpracování dotazu bude plná deklarovaná velikost pole vtažena do paměti RAM. Pokud tedy máte varchar(256), ale používáte pouze 4 znaky, stále platíte za využití 256 bajtů RAM, zatímco se dotaz zpracovává. Au! Takže pokud můžete snadno zmenšit své varchar limity, mělo by to urychlit vaše dotazy.

(těžší) – Normalizovat

30 % vašich řádků s hodnotou jednoho řetězce je jasným voláním po normalizaci do jiné tabulky, abyste neduplikovali řetězce milionkrát. Zvažte normalizaci do tří tabulek a jejich spojení pomocí celočíselných ID.

V některých případech můžete normalizovat pod krytem a skrýt normalizaci pomocí pohledů, které odpovídají názvu aktuální tabulky... pak stačí, abyste si normalizaci uvědomili ve svých dotazech INSERT/UPDATE/DELETE, ale své SELECTy můžete nechat být. .

(nejtěžší) – Hašujte sloupce řetězců a indexujte hodnoty hash

Pokud normalizace znamená změnu příliš velkého množství kódu, ale můžete trochu změnit své schéma, můžete zvážit vytvoření 128bitových hash pro sloupce řetězců (pomocí Funkce MD5 ). V tomto případě (na rozdíl od normalizace) nemusíte měnit všechny své dotazy, pouze INSERTy a některé SELECTy. Každopádně budete chtít svá pole řetězců hashovat a poté vytvořit index na hash, např.

CREATE INDEX ix_temp ON relations (relation_title_hash, object_title_hash);

Všimněte si, že si budete muset pohrát s SELECT, abyste se ujistili, že výpočet provádíte pomocí hash indexu a nikoli stahováním seskupeného indexu (vyžaduje se k vyřešení skutečné textové hodnoty object_title, aby bylo vyhověno dotazu).

Také pokud má relace_title malou velikost varchar, ale název objektu má dlouhou velikost, můžete potenciálně hashovat pouze object_title a vytvořit index na (relation_title, object_title_hash) .

Všimněte si, že toto řešení pomáhá pouze v případě, že jedno nebo obě tato pole jsou velmi dlouhá vzhledem k velikosti hashů.

Všimněte si také, že hašování má zajímavé dopady na rozlišování velkých a malých písmen a řazení, protože hash řetězce s malými písmeny není stejný jako hash řetězce s velkými písmeny. Takže se musíte ujistit, že na řetězce aplikujete kanonizaci, než je zahašujete – jinými slovy, hashujte pouze malá písmena, pokud jste v databázi bez rozlišování velkých a malých písmen. Můžete také chtít oříznout mezery od začátku nebo konce, v závislosti na tom, jak vaše databáze zpracovává úvodní/koncové mezery.



  1. Získat součin řádků (násobení)

  2. Oracle:Převod částky měny ve slovech pomocí PL/SQL

  3. Přetrvávající UUID v PostgreSQL pomocí JPA

  4. Jak mohu odeslat e-mail ze spouštěče PostgreSQL?