Nein. Wenn Ihre Tabelle über die InnoDB-Engine und die PRIMARY KEY
is verfügt (pet_id)
, definiert die Definition eines Sekundärindex keinen (person_id)
oder (person_id, pet_id)
keinen Unterschied.
Der Index enthält auch die pet_id
Spalte, sodass die Werte wie (person_id, pet_id)
in beiden Fällen sortiert sind.
Eine Abfrage wie die, die Sie haben:
SELECT pet_id FROM yourtable
WHERE person_id = 127
ORDER BY pet_id ;
muss nur auf den Index zugreifen, um die Werte zu erhalten, und noch mehr, es muss keine Sortierung durchgeführt werden, da die pet_id
Werte bereits im Index sortiert sind. Sie können dies überprüfen, indem Sie sich die Ausführungspläne ( EXPLAIN
) ansehen :
Zuerst versuchen wir es mit einer MyISAM-Tabelle:
CREATE TABLE table pets
( pet_id int not null auto_increment PRIMARY KEY,
person_id int not null,
INDEX person_ix (person_id)
) ENGINE = myisam ;
INSERT INTO pets (person_id)
VALUES (1),(2),(3),(1),(2),(3),(4),(1),(8),(1),(2),(3) ;
mysql> EXPLAIN SELECT pet_id FROM pets
WHERE person_id = 2
ORDER BY pet_id asc \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: pets
type: ref
possible_keys: person_ix
key: person_ix
key_len: 4
ref: const
rows: 3
Extra: Using where; Using filesort
1 row in set (0.00 sec)
Beachten Sie die Dateisortierung!
Jetzt MyISAM mit zusammengesetztem Index:
DROP TABLE IF EXISTS pets ;
CREATE TABLE table pets
( pet_id int not null auto_increment PRIMARY KEY,
person_id int not null,
INDEX person_ix (person_id, pet_id) -- composite index
) ENGINE = myisam ;
INSERT INTO pets (person_id)
VALUES (1),(2),(3),(1),(2),(3),(4),(1),(8),(1),(2),(3) ;
mysql> EXPLAIN SELECT pet_id FROM pets
WHERE person_id = 2
ORDER BY pet_id asc \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: pets
type: ref
possible_keys: person_ix
key: person_ix
key_len: 4
ref: const
rows: 3
Extra: Using where; Using index
1 row in set (0.00 sec)
Filesort ist wie erwartet weg .
Versuchen wir jetzt dasselbe mit der InnoDB-Engine:
DROP TABLE IF EXISTS pets ;
CREATE TABLE table pets
( pet_id int not null auto_increment PRIMARY KEY,
person_id int not null,
INDEX person_ix (person_id) -- simple index
) ENGINE = innodb ; -- InnoDB engine
INSERT INTO pets (person_id)
VALUES (1),(2),(3),(1),(2),(3),(4),(1),(8),(1),(2),(3) ;
mysql> EXPLAIN SELECT pet_id FROM pets
WHERE person_id = 2
ORDER BY pet_id asc \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: pets
type: ref
possible_keys: person_ix
key: person_ix
key_len: 4
ref: const
rows: 3
Extra: Using where; Using index
1 row in set (0.00 sec)
Auch kein Dateisort! Obwohl der Index die pet_id
Spalte nicht explizit enthält, sind die Werte vorhanden und sortiert. Sie können überprüfen , dass , wenn Sie den Index mit definieren (person_id, pet_id)
, die EXPLAIN
identisch ist.
Machen wir es tatsächlich mit InnoDB und dem zusammengesetzten Index:
DROP TABLE IF EXISTS pets ;
CREATE TABLE table pets
( pet_id int not null auto_increment PRIMARY KEY,
person_id int not null,
INDEX person_ix (person_id, pet_id) -- composite index
) ENGINE = innodb ; -- InnoDB engine
INSERT INTO pets (person_id)
VALUES (1),(2),(3),(1),(2),(3),(4),(1),(8),(1),(2),(3) ;
mysql> EXPLAIN SELECT pet_id FROM pets
WHERE person_id = 2
ORDER BY pet_id asc \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: pets
type: ref
possible_keys: person_ix
key: person_ix
key_len: 4
ref: const
rows: 3
Extra: Using where; Using index
1 row in set (0.00 sec)
Identische Pläne mit dem vorherigen Fall.
Um 100% sicher zu sein, führe ich auch die letzten beiden Fälle aus (InnoDB-Engine mit einzelnen und zusammengesetzten Indizes), um die file_per_table
Einstellung zu ermöglichen und der Tabelle einige tausend Zeilen hinzuzufügen:
DROP TABLE IF EXISTS ... ;
CREATE TABLE ... ;
mysql> INSERT INTO pets (person_id)
VALUES (1),(2),(3),(1),(2),(3),(4),(1),(8),(1),(2),(3) ;
Query OK, 12 rows affected (0.00 sec)
Records: 12 Duplicates: 0 Warnings: 0
mysql> INSERT INTO pets (person_id)
VALUES (1),(2),(3),(1),(2),(3),(4),(1),(8),(1),(2),(3),(127) ;
Query OK, 13 rows affected (0.00 sec)
Records: 13 Duplicates: 0 Warnings: 0
mysql> INSERT INTO pets (person_id)
VALUES (1),(2),(3),(1),(2),(3),(4),(1),(8),(1),(2),(3),(127) ;
Query OK, 13 rows affected (0.00 sec)
Records: 13 Duplicates: 0 Warnings: 0
mysql> INSERT INTO pets (person_id)
SELECT a.person_id+b.person_id-1
FROM pets a CROSS JOIN pets b CROSS JOIN pets c ;
Query OK, 54872 rows affected (0.47 sec)
Records: 54872 Duplicates: 0 Warnings: 0
In beiden Fällen führt die Überprüfung der tatsächlichen Dateigrößen zu identischen Ergebnissen :
ypercube@apollo:~$ sudo ls -la /var/lib/mysql/x/ | grep pets
-rw-rw---- 1 mysql mysql 8604 Apr 21 07:25 pets.frm
-rw-rw---- 1 mysql mysql 11534336 Apr 21 07:25 pets.ibd
person_id
nicht eindeutig sind, werden Datensätze physisch nach(person_id, pet_id)
oder NUR sortiertperson_id
?"