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.