MySQL
Index och nycklar
Sök…
Syntax
- Skapa enkelt index
SKAPA INDEX indexnamn PÅ tabellnamn ( kolumnnamn1 [, kolumnnamn2 , ...])
- Skapa unikt index
SKAPA UNIK INDEX indexnamn PÅ tabellnamn ( kolumnnamn1 [, kolumnnamn2 , ...]
- Drop index
DROP INDEX indexnamn PÅ tbl_namn [ algoritm_option | lock_option ] ...
algoritm_option: ALGORITHM [=] {DEFAULT | INPLACE | COPY}
lock_option: LOCK [=] {DEFAULT | INGEN | DELAD | EXKLUSIVT}
Anmärkningar
begrepp
Ett index i en MySQL-tabell fungerar som ett index i en bok.
Låt oss säga att du har en bok om databaser och att du vill hitta lite information om, säg, lagring. Utan ett index (förutsatt att inget annat stöd, till exempel en innehållsförteckning), måste du gå igenom sidorna en efter en tills du hittade ämnet (det är en "fullständig tabellscanning"). Å andra sidan har ett index en lista med nyckelord, så du konsulterar indexet och ser att lagring nämns på sidorna 113-120, 231 och 354. Då kan du bläddra direkt till dessa sidor utan att söka (det är en sökning med ett index, något snabbare).
Naturligtvis beror användbarheten av indexet på många saker - några exempel med similen ovan:
- Om du hade en bok om databaser och indexerade ordet "databas", kan du se att den nämns på sidorna 1-59, 61-290 och 292-400. Det är många sidor, och i ett sådant fall hjälper inte indexet mycket och det kan vara snabbare att gå igenom sidorna en efter en. (I en databas är detta "dålig selektivitet".)
- För en bok på 10 sidor är det inte meningsfullt att skapa ett index, eftersom du kan sluta med en 10-sidars bok förinställd av ett 5-sidigt index, vilket bara är dumt - bara skanna de 10 sidorna och gör det med det .
- Indexet måste också vara användbart - det finns i allmänhet ingen mening med att indexera, till exempel frekvensen för bokstaven "L" per sida.
Skapa index
-- Create an index for column 'name' in table 'my_table'
CREATE INDEX idx_name ON my_table(name);
Skapa unikt index
Ett unikt index förhindrar att duplicerade data införs i en tabell. NULL värden kan infogas i kolumnerna som utgör en del av det unika indexet (eftersom, per definition, ett NULL värde skiljer sig från något annat värde, inklusive ett annat NULL värde)
-- Creates a unique index for column 'name' in table 'my_table'
CREATE UNIQUE INDEX idx_name ON my_table(name);
Släpp index
-- Drop an index for column 'name' in table 'my_table'
DROP INDEX idx_name ON my_table;
Skapa sammansatt index
Detta skapar ett sammansatt index av båda nycklarna, mystring och mydatetime och påskyndar frågor med båda kolumnerna i WHERE klausulen.
CREATE INDEX idx_mycol_myothercol ON my_table(mycol, myothercol)
Obs! Beställningen är viktig! Om sökfrågan inte innehåller båda kolumnerna i WHERE klausulen kan den bara använda det vänstra indexet. I det här fallet kommer en fråga med mycol i WHERE att använda indexet, en fråga som söker efter myothercol utan att också söka efter mycol kommer inte . För mer information, kolla in detta blogginlägg .
Obs: På grund av hur BTREE arbetar, bör kolumner som vanligtvis fråges i intervaller gå längst till höger. Till exempel DATETIME kolumner vanligtvis som WHERE datecol > '2016-01-01 00:00:00' . BTREE-indexhandtaget sträcker sig mycket effektivt men bara om kolumnen som fråges som ett intervall är den sista i kompositindex.
AUTO_INCREMENT-tangent
CREATE TABLE (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY(id),
... );
Huvudanmärkningar:
- Börjar med 1 och steg med 1 automatiskt när du inte anger det på
INSERTeller anger det somNULL. - ID: er skiljer sig alltid från varandra, men ...
- Anta inga antaganden (inga luckor, genereras i följd, inte återanvändas, osv.) Om värdena på iden annat än att vara unik vid ett visst ögonblick.
Subtila anteckningar:
- Vid omstart av servern beräknas 'nästa' värde som
MAX(id)+1. - Om den senaste åtgärden innan avstängning eller kraschen var att ta bort den högsta id kan att id återanvändas (detta är motorberoende). Så lita inte på att auto_inkrement är permanent unika ; de är bara unika när som helst.
- För lösningar med flera master eller kluster, se
auto_increment_offsetochauto_increment_increment. - Det är OK att ha något annat som
PRIMARY KEYoch helt enkelt göraINDEX(id). (Detta är en optimering i vissa situationer.) - Att använda
AUTO_INCREMENTsom "PARTITIONnyckel" är sällan fördelaktigt; gör något annorlunda. - Olika operationer kan "bränna" värden. Detta händer när de fördelar värde (er) och sedan inte använder dem:
INSERT IGNORE(med dup-nyckel),REPLACE(som ärDELETEplusINSERT) och andra.ROLLBACKär en annan orsak till luckor i ID: er. - I replikering kan du inte lita på id: er för att komma fram till slaven i stigande ordning. Även om ID: er tilldelas i ordning i följd, skickas InnoDB-uttalanden till slavar i
COMMITordning.