Tidak. Jika tabel Anda memiliki mesin InnoDB dan PRIMARY KEY
itu (pet_id)
, maka mendefinisikan indeks sekunder sebagai (person_id)
atau (person_id, pet_id)
tidak ada bedanya.
Indeks juga menyertakan pet_id
kolom sehingga nilai diurutkan seperti (person_id, pet_id)
dalam kedua kasus.
Kueri seperti yang Anda miliki:
SELECT pet_id FROM yourtable
WHERE person_id = 127
ORDER BY pet_id ;
Anda hanya perlu mengakses indeks untuk mendapatkan nilai dan bahkan lebih, itu tidak perlu melakukan apa pun, karena pet_id
nilai sudah diurutkan dalam indeks. Anda dapat memverifikasi ini dengan melihat rencana eksekusi ( EXPLAIN
):
Pertama, kami mencoba dengan tabel MyISAM:
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)
Perhatikan filesort!
Sekarang, MyISAM dengan indeks komposit:
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 hilang , seperti yang diharapkan.
Sekarang mari kita coba hal yang sama dengan mesin InnoDB:
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)
Juga tidak ada filesort! Meskipun indeks tidak secara eksplisit memiliki pet_id
kolom, nilainya ada di sana dan diurutkan. Anda dapat memeriksa bahwa jika Anda mendefinisikan indeks dengan (person_id, pet_id)
, EXPLAIN
identik.
Mari kita benar-benar melakukannya, dengan InnoDB dan indeks komposit:
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)
Rencana identik dengan kasus sebelumnya.
Agar 100% yakin, saya juga menjalankan 2 case terakhir (mesin InnoDB, dengan indeks tunggal dan komposit) memungkinkan file_per_table
pengaturan dan menambahkan beberapa ribu baris dalam tabel:
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
Dalam kedua kasus, memeriksa ukuran file aktual, menghasilkan hasil yang identik :
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
tidak unik, apakah catatan secara fisik disortir oleh(person_id, pet_id)
atau HANYAperson_id
?"