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å
INSERT
eller 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_offset
ochauto_increment_increment
. - Det är OK att ha något annat som
PRIMARY KEY
och helt enkelt göraINDEX(id)
. (Detta är en optimering i vissa situationer.) - Att använda
AUTO_INCREMENT
som "PARTITION
nyckel" ä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 ärDELETE
plusINSERT
) 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
COMMIT
ordning.