12.為表的字段創建索引


數據庫索引就象書的目錄一樣,如果在字段上建立了索引,那么以索引列為查詢條件時 可以加快查詢數據的速度 查詢數據庫,按主鍵查詢是最快的,每個表只能有一個主鍵列,但是可以有多個普通索 引列,主鍵列要求列的所有內容必須唯一,而普通索引列不要求內容必須唯一 主鍵就類似我們在學校學習時的學號一樣,班級里是唯一的,整個表的每一條記錄的 鍵值在表內都是唯一的,用來唯一標識一條記錄。

12.1 為表創建主鍵索引的方法

mysql> use oldboy
Database changed
mysql> create table student(
 -> id int(4) not null AUTO_INCREMENT,
 -> name char(20) not null,
 -> age tinyint(2) not null default '0',
-> dept varchar(16) default null,
->primary key(id),
->KEY index_name(name)
->);​

 

提示:
primary key(id) <-主鍵
KEY index_name(name) <-name 字段普通索引
只有 int 類型且為 primary key 才可以使用 auto_increment

12.2 查看 student 表的結構

mysql> show create table student\G;
*************************** 1. row ***************************
 Table: student
Create Table: CREATE TABLE `student` (
 `id` int(4) NOT NULL AUTO_INCREMENT,
 `name` char(20) NOT NULL,
 `age` tinyint(2) NOT NULL DEFAULT '0',
 `dept` varchar(16) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `index_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> describe student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | char(20) | NO | MUL | NULL | |
| age | tinyint(2) | NO | | 0 | |
| dept | varchar(16) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)​

 

12.3 怎么刪除一個表的主鍵

mysql> alter table student drop primary key;​

 

提示:如果一個表中的 primary key 設置了 AUTO_INCREMENT(自動增加)的話,就刪不掉

12.4 利用 alter 命令修改 id 列為自增主鍵列

mysql> alter table student change id id int primary key auto_increment;

 

12.5 建表后利用 alter 增加普通索引

刪除建表時創建的 index_name 索引
mysql> select database();
+------------+
| database()
+------------+
| oldboy |
+------------+
1 row in set (0.00 sec)
mysql> show create table student;
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--------------------------------+
| Table | Create Table
|
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--------------------------------+
| student | CREATE TABLE `student` (
 `id` int(4) NOT NULL AUTO_INCREMENT,
 `name` char(20) NOT NULL,
 `age` tinyint(2) NOT NULL DEFAULT '0',
 `dept` varchar(16) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `index_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--------------------------------+
1 row in set (0.00 sec)
刪除普通索引
mysql> alter table student drop index index_name;
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table student;
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
---+
| Table | Create Table
|
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
---+
| student | CREATE TABLE `student` (
 `id` int(4) NOT NULL AUTO_INCREMENT,
 `name` char(20) NOT NULL,
 `age` tinyint(2) NOT NULL DEFAULT '0',
 `dept` varchar(16) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
---+
1 row in set (0.00 sec)
創建普通索引
mysql> use oldboy
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> alter table student add index index_name (name);
Query OK, 0 rows affected (0.47 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table student;
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--------------------------------+
| Table | Create Table
|
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--------------------------------+
| student | CREATE TABLE `student` (
 `id` int(4) NOT NULL AUTO_INCREMENT,
 `name` char(20) NOT NULL,
 `age` tinyint(2) NOT NULL DEFAULT '0',
 `dept` varchar(16) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `index_name` (`name`) 提示:訪問數據量很大的時候,不適合建立普通索引,會影響
用戶訪問,盡量選擇業務低估時建立索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--------------------------------+
1 row in set (0.00 sec)​

 

 12.6 對表字段的前 n 個字符創建普通索引

當遇到表中比較大的列時,列內容的前 n 個字符在所有內容中已接近唯一時,這時可以對列的前 n 個字符建立索引,而無需對整個列建立本索引,這樣可以節省創建索引占用的系統空間,以及降低讀取和更新維護索引消耗的系統資源。
對字段前 n 個字符創建普通索引的語法:
create index index_name on student(name(8));條件列前 N 個字符創建索引
下面來實戰演示:

mysql> select database();
+------------+
| database() |
+------------+
| oldboy |
+------------+
1 row in set (0.00 sec)
為 dept 列前八個字符創建普通索引
mysql> describe student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | char(20) | NO | MUL | NULL | |
| age | tinyint(2) | NO | | 0 | |
| dept | varchar(16) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> create index index_name_dept on student (dept(8));
Query OK, 0 rows affected (0.21 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> describe student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | char(20) | NO | MUL | NULL | |
| age | tinyint(2) | NO | | 0 | |
| dept | varchar(16) | YES | MUL | NULL | |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> show create table student;
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------+
| Table | Create Table
|
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------+
| student | CREATE TABLE `student` (
 `id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
 `age` tinyint(2) NOT NULL DEFAULT '0',
 `dept` varchar(16) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `index_name` (`name`),
 KEY `index_name_dept` (`dept`(8))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------+
1 row in set (0.00 sec)​

 

另外一種建立表后創建普通索引的方法:

mysql> alter table student add index index_name_dept (dept(8));​

 

12.7 為表的多個字段創建聯合索引

如何查詢數據的條件時多列時,我們可以為多個查詢的列創建聯合索引,甚至,可以為多列的前 n 個字符列創建聯合索引,實戰演示如下:

mysql> create index index_name_and_dept on student (name,dept);
Query OK, 0 rows affected (0.11 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table student;
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------+
| Table | Create Table
|
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE `student` (
 `id` int(4) NOT NULL AUTO_INCREMENT,
 `name` char(20) NOT NULL,
 `age` tinyint(2) NOT NULL DEFAULT '0',
 `dept` varchar(16) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `index_name` (`name`),
 KEY `index_name_dept` (`dept`(8)),
 KEY `index_name_and_dept` (`name`,`dept`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)​

 

12.8 為表的多個字段的前 n 個字符創建聯合索引

mysql> create index index_name_and_dept on student (name(10),dept(10));
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table student;
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
----+
| Table | Create Table
|
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
----+
| student | CREATE TABLE `student` (
 `id` int(4) NOT NULL AUTO_INCREMENT,
 `name` char(20) NOT NULL,
 `age` tinyint(2) NOT NULL DEFAULT '0',
 `dept` varchar(16) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `index_name` (`name`),
 KEY `index_name_dept` (`dept`(8)),
 KEY `index_name_and_dept` (`name`(10),`dept`(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
----+
1 row in set (0.00 sec)​

 

提示:按條件列查詢數據時,聯合索引是有前綴生效特性的
index(a,b,c)僅 a,ab,abc 三個查詢條件列可以走索引,b,bc,ac,c 等無法使用索引了

盡量把最常用作為查詢條件的列,放在第一位置

12.9 主鍵也可以聯合多列做索引

*************************** 1. row ***************************
 Table: user
Create Table: CREATE TABLE `user` (
 `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
 `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '',
 `Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
 `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
 `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT
'',
 `ssl_cipher` blob NOT NULL,
 `x509_issuer` blob NOT NULL,
 `x509_subject` blob NOT NULL,
 `max_questions` int(11) unsigned NOT NULL DEFAULT '0',
 `max_updates` int(11) unsigned NOT NULL DEFAULT '0',
 `max_connections` int(11) unsigned NOT NULL DEFAULT '0',
 `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
 `plugin` char(64) COLLATE utf8_bin DEFAULT '',
 `authentication_string` text COLLATE utf8_bin,
 PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and
global privileges'
1 row in set (0.00 sec)
ERROR:
No query specified​ 

 

12.10  統計一個字段列的唯一值個數

  1. mysql> select user from mysql.user;
    +-----------+
    | user |
    +-----------+
    | root |
    | blog |
    | oldgirl |
    | wordpress |
    | oldgirl |
    | oldboy |
    | oldgirl |
    | root |
    +-----------+
    8 rows in set (0.00 sec)
    mysql> select count(distinct user) from mysql.user;
    +----------------------+
    | count(distinct user) |
    +----------------------+
    | 5 |
    +----------------------+
    1 row in set (0.06 sec)
    提示:盡量在唯一值多的大表上建立索引​

     

12.11  創建唯一索引(非主鍵)

mysql> show create table student ;
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--------------------------------------+
| Table | Create Table
|
+---------+----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--------------------------------------+
| student | CREATE TABLE `student` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` char(20) NOT NULL,
`age` tinyint(2) NOT NULL DEFAULT '0',
`dept` varchar(16) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `index_age` (`age`),
KEY `index_name` (`name`),
KEY `index_name_dept` (`dept`(8)),
KEY `index_name_and_dept` (`name`(10),`dept`(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+----------------------------------------------------------------------------------------------------------
1 row in set (0.00 sec)​

 

12.12  索引列的創建及生效條件

問題一:既然索引可以加快查詢速度,那么就給所有的列建索引吧?
解答:因為索引不但占用系統空間,而且更新數據時還需要維護索引數據的,因此,索引是一把雙刃劍,並不是越多越好,例如:數十到幾百行的小表上無需建立索引,更新頻繁,讀取比較少的表要少建立索引
問題二:需要在哪些列上創建索引了?
解答:select user,host from mysql.user where password=...,索引一定要創建在 where 后的條件列上,而不是 select 后的選擇數據的列上,另外,我們要盡量選擇在唯一值多的大表上的列建立索引,例如:男女性別列唯一值,不適合建立索引


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM