it-swarm-eu.dev

Možný INDEX na poli VARCHAR v MySql

Pracuji v MySql databáze, s tabulkou takto:

+--------------+
|  table_name  |
+--------------+
|    myField   |
+--------------+

... a musím udělat hodně podobných dotazů (s 5-10 řetězci v seznamu) :

SELECT myField FROM table_name
WHERE myField IN ('something', 'other stuff', 'some other a bit longer'...)

Bude jich kolem 24 000 000 jedinečné řádky

1) Měl bych pro svou VARCHAR(150) použít klíč FULLTEXT nebo INDEX?
2) Pokud zvýším charty ze 150 na 220 nebo 250 ... bude to velký rozdíl? (Existuje způsob, jak to spočítat?)
[.____. ) Jak jsem řekl, budou jedinečné, takže myField by měl být - PRIMÁRNÍ KLÍČ. Není vzácné přidat PRIMÁRNÍ KLÁVES do pole, které je již VARCHAR INDEX/FULLTEXT?

43
Mark Tower

NÁVRH # 1: Standardní indexování

CREATE TABLE mytable
(
    id int not null auto_increment,
    myfield varchar(255) not null,
    primary key (id),
    key (myfield)
);

Pokud takhle indexujete, můžete hledat celý řetězec nebo hledat LIKE orientované doleva

SUGGESTION # 2: FULLTEXT Indexing

CREATE TABLE mytable
(
    id int not null auto_increment,
    myfield varchar(255) not null,
    primary key (id),
    fulltext (myfield)
);

Můžete efektivně využívat vyhledávání jednotlivých klíčových slov i celých frází. Budete muset definovat vlastní seznam zastavovacích slov, protože MySQL nebude indexovat 543 slov .

Zde jsou mé další příspěvky z posledních dvou let na indexy FULLTEXT

SUGGESTION # 3: Hash Indexing

CREATE TABLE mytable
(
    id int not null auto_increment,
    myfield varchar(255) not null,
    hashmyfield char(32) not null,
    primary key (id),
    key (hashmyfield)
);

Pokud hledáte jednu konkrétní hodnotu a tyto hodnoty mohou být délky značně přesahující 32 znaků, můžete uložit hodnotu hash:

INSERT INTO mytable (myfield,hashmyfield)
VALUES ('whatever',MD5('whatever'));

Tímto způsobem stačí vyhledat hodnoty hash a načíst výsledky

SELECT * FROM mytable WHERE hashmyfield = MD5('whatever');

Pokusit se !!!

69
RolandoMySQLDBA

MySQL vám umožňuje definovat předponovaný index, což znamená, že definujete prvních N znaků z původního řetězce, který má být indexován, a trik spočívá v tom, že si vyberete číslo N, které je dostatečně dlouhé, aby poskytovalo dobrou selektivitu, ale dostatečně krátké, aby ušetřilo místo. Předpona by měla být dostatečně dlouhá, aby byl index téměř stejně užitečný, jako by byl, kdybyste indexovali celý sloupec.

Než půjdeme dále, definujme některé důležité pojmy. Selektivita indexu je poměr celkové odlišné indexované hodnoty a celkový počet řádků. Zde je jeden příklad pro testovací tabulku:

+-----+-----------+
| id  | value     |
+-----+-----------+
| 1   | abc       |
| 2   | abd       |
| 3   | adg       |
+-----+-----------+

Pokud indexujeme pouze první znak (N = 1), bude indexová tabulka vypadat jako následující tabulka:

+---------------+-----------+
| indexedValue  | rows      |
+---------------+-----------+
| a             | 1,2,3     |
+---------------+-----------+

V tomto případě se selektivita indexu rovná IS = 1/3 = 0,33.

Podívejme se nyní, co se stane, pokud zvýšíme počet indexovaných znaků na dva (N = 2).

+---------------+-----------+
| indexedValue  | rows      |
+---------------+-----------+
| ab             | 1,2      |
| ad             | 3        |
+---------------+-----------+

V tomto scénáři IS = 2/3 = 0,66, což znamená, že jsme zvýšili selektivitu indexu, ale také jsme zvýšili velikost indexu. Trik je najít minimální číslo N, které povede k maximální index selektivita.

Existují dva přístupy, které můžete provádět výpočty pro vaši databázovou tabulku. Udělám demonstraci na tento výpis z databáze .

Řekněme, že chceme do indexu přidat sloupec last_name v tabulce zaměstnanci a chceme definovat nejmenší číslo N , která zajistí nejlepší selektivitu indexu.

Nejprve určíme nejčastější příjmení:

select count(*) as cnt, last_name from employees group by employees.last_name order by cnt

+-----+-------------+
| cnt | last_name   |
+-----+-------------+
| 226 | Baba        |
| 223 | Coorg       |
| 223 | Gelosh      |
| 222 | Farris      |
| 222 | Sudbeck     |
| 221 | Adachi      |
| 220 | Osgood      |
| 218 | Neiman      |
| 218 | Mandell     |
| 218 | Masada      |
| 217 | Boudaillier |
| 217 | Wendorf     |
| 216 | Pettis      |
| 216 | Solares     |
| 216 | Mahnke      |
+-----+-------------+
15 rows in set (0.64 sec)

Jak vidíte, příjmení Baba je nejčastější. Nyní najdeme nejčastěji se vyskytující předpony last_name, počínaje předpony pěti písmen.

+-----+--------+
| cnt | prefix |
+-----+--------+
| 794 | Schaa  |
| 758 | Mande  |
| 711 | Schwa  |
| 562 | Angel  |
| 561 | Gecse  |
| 555 | Delgr  |
| 550 | Berna  |
| 547 | Peter  |
| 543 | Cappe  |
| 539 | Stran  |
| 534 | Canna  |
| 485 | Georg  |
| 417 | Neima  |
| 398 | Petti  |
| 398 | Duclo  |
+-----+--------+
15 rows in set (0.55 sec)

Každá předpona se vyskytuje mnohem více, což znamená, že musíme zvyšovat počet N, dokud nebudou hodnoty téměř stejné jako v předchozím příkladu.

Zde jsou výsledky pro N = 9

select count(*) as cnt, left(last_name,9) as prefix from employees group by prefix order by cnt desc limit 0,15;

+-----+-----------+
| cnt | prefix    |
+-----+-----------+
| 336 | Schwartzb |
| 226 | Baba      |
| 223 | Coorg     |
| 223 | Gelosh    |
| 222 | Sudbeck   |
| 222 | Farris    |
| 221 | Adachi    |
| 220 | Osgood    |
| 218 | Mandell   |
| 218 | Neiman    |
| 218 | Masada    |
| 217 | Wendorf   |
| 217 | Boudailli |
| 216 | Cummings  |
| 216 | Pettis    |
+-----+-----------+

Zde jsou výsledky pro N = 10.

+-----+------------+
| cnt | prefix     |
+-----+------------+
| 226 | Baba       |
| 223 | Coorg      |
| 223 | Gelosh     |
| 222 | Sudbeck    |
| 222 | Farris     |
| 221 | Adachi     |
| 220 | Osgood     |
| 218 | Mandell    |
| 218 | Neiman     |
| 218 | Masada     |
| 217 | Wendorf    |
| 217 | Boudaillie |
| 216 | Cummings   |
| 216 | Pettis     |
| 216 | Solares    |
+-----+------------+
15 rows in set (0.56 sec)

To jsou velmi dobré výsledky. To znamená, že můžeme vytvořit index ve sloupci last_name s indexováním pouze prvních 10 znaků. Ve sloupci definice tabulky last_name je definováno jako VARCHAR(16), a to znamená, že jsme uložili 6 bajtů (nebo více, pokud jsou v příjmení UTF8 znaky) na položku. V této tabulce je 1637 různých hodnot vynásobených 6 bajty je asi 9 kB a představte si, jak by toto číslo vzrostlo, kdyby naše tabulka obsahovala miliony řádků.

V mém příspěvku si můžete přečíst další způsoby výpočtu počtu N Předponované indexy v MySQL .

Použití funkcí MD5 a SHA1 za účelem generování hodnot, které by měly být indexovány, také není dobrý přístup . Proč? Přečtěte si to poštou Jak zvolit správný datový typ pro primární klíč v databázi MySQL

18
Mr.M