一、MySQL索引的类型
MySQL支持多种类型的索引,每种类型都有其特点和适用场景。以下是一些常见的索引类型:
- 普通索引(INDEX):最基本的索引类型,没有任何限制。
- 唯一索引(UNIQUE):与普通索引类似,但具有唯一性约束,即索引列的值必须唯一。
- 全文索引(FULLTEXT):仅适用于MyISAM引擎,主要用于解决针对文本的模糊查询问题,如WHERE name LIKE “%word%"。全文索引只能在CHAR、VARCHAR和TEXT列上创建。
- 单列索引(SPATIAL):空间索引,用于地理空间数据类型的查询,如GEOMETRY、POINT、LINESTRING等。
- 多列索引(SPATIAL):也称为复合索引,即一个索引包含多个列。
- 哈希索引(HASH):由于HASH的唯一性(几乎100%的唯一)及类似键值对的形式,很适合作为索引。HASH索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率。
- B树索引(BTREE):B树是一种自平衡的多路搜索树,它能保持数据有序,并且具有很好的查询性能。MySQL中的InnoDB存储引擎使用的是B+树索引。
- R树索引(RTREE):R树是一种基于区域划分的空间索引结构,用于处理二维或多维空间数据的查询。
以上是MySQL中常用的一些索引类型,它们各有特点和用途,可以根据实际需求选择适合的索引类型来提高查询性能
二、索引的使用
1.普通索引(INDEX)
普通索引是MySQL中最基本的索引类型之一,它没有任何限制。以下是一些使用普通索引的示例:
1)创建普通索引:
CREATE TABLE `table_name` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
INDEX index_name (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
在这个例子中,我们为name
字段创建了一个名为index_name
的普通索引。
2)查询时使用普通索引:
SELECT * FROM `table_name` WHERE `name` = 'John';
在这个例子中,我们在查询条件中使用了name
字段,并且该字段上已经创建了普通索引。因此,MySQL可以使用该索引来加速查询。
3)强制使用普通索引:
SELECT * FROM `table_name` FORCE INDEX (`index_name`) WHERE `name` = 'John';
在这个例子中,我们使用了FORCE INDEX关键字来强制查询优化器使用名为index_name
的普通索引进行查询。
4)使用USE INDEX语句:
SELECT * FROM `table_name` USE INDEX (`index_name`) WHERE `name` = 'John';
在这个例子中,我们使用了USE INDEX关键字来让查询优化器选择名为index_name
的普通索引进行查询。
这些示例展示了如何使用普通索引来提高查询性能。在实际使用时,需要根据具体情况和需求选择合适的索引类型和列。
2.唯一索引(UNIQUE)
唯一索引是MySQL中一种限制字段值唯一性的索引类型。以下是一些使用唯一索引的示例:
1)创建唯一索引:
CREATE TABLE `table_name` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX unique_email (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
在这个例子中,我们为email
字段创建了一个名为unique_email
的唯一索引。由于该字段上已经创建了唯一索引,因此每个邮箱地址在该表中只能出现一次。
2)插入数据时检查唯一性:
INSERT INTO `table_name` (`email`) VALUES ('john@example.com');
在这个例子中,我们尝试向表中插入一个已经存在的邮箱地址。由于该字段上已经创建了唯一索引,因此插入操作会失败并抛出一个错误。
3)查询时使用唯一索引:
SELECT * FROM `table_name` WHERE `email` = 'john@example.com';
在这个例子中,我们在查询条件中使用了email
字段,并且该字段上已经创建了唯一索引。因此,MySQL可以使用该索引来加速查询。
4)强制使用唯一索引:
SELECT * FROM `table_name` FORCE INDEX (`unique_email`)
WHERE `email` = 'john@example.com';
在这个例子中,我们使用了FORCE INDEX关键字来强制查询优化器使用名为unique_email
的唯一索引进行查询。
这些示例展示了如何使用唯一索引来保证字段值的唯一性并提高查询性能。在实际使用时,需要根据具体情况和需求选择合适的索引类型和列。
3.全文索引(FULLTEXT)
全文索引是MySQL中一种用于全文搜索的索引类型。以下是一些使用全文索引的示例:
1)创建全文索引:
CREATE TABLE `table_name` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`content` text NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT INDEX fulltext_index (`content`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
在这个例子中,我们为content
字段创建了一个名为fulltext_index
的全文索引。由于该字段上已经创建了全文索引,因此可以进行全文搜索。
2)插入数据时添加全文索引:
INSERT INTO `table_name` (`content`)
VALUES ('This is a sample text for full-text search.');
在这个例子中,我们在插入数据时直接将文本添加到了content
字段中。由于该字段上已经创建了全文索引,因此可以对该文本进行全文搜索。
3)查询时使用全文索引:
SELECT * FROM `table_name` WHERE MATCH(`content`)
AGAINST('sample' IN NATURAL LANGUAGE MODE);
在这个例子中,我们在查询条件中使用了MATCH和AGAINST关键字来进行全文搜索。由于该字段上已经创建了全文索引,因此MySQL可以使用该索引来加速查询。
4)强制使用全文索引:
SELECT * FROM `table_name` FORCE INDEX (`fulltext_index`)
WHERE MATCH(`content`) AGAINST('sample' IN NATURAL LANGUAGE MODE);
在这个例子中,我们使用了FORCE INDEX关键字来强制查询优化器使用名为fulltext_index
的全文索引进行查询。
这些示例展示了如何使用全文索引来进行全文搜索并提高查询性能。在实际使用时,需要根据具体情况和需求选择合适的索引类型和列。
4.单列索引(SPATIAL)
单列索引(SPATIAL)是MySQL中一种用于地理空间数据类型的索引类型。以下是一些使用单列索引(SPATIAL)的示例:
1)创建表并添加地理空间数据类型:
CREATE TABLE `table_name` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`location` point NOT NULL,
PRIMARY KEY (`id`), SPATIAL INDEX (`location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
在这个例子中,我们为location
字段创建了一个名为SPATIAL INDEX
的单列索引。由于该字段上已经创建了单列索引,因此可以进行地理空间查询。
2)插入数据时添加地理空间数据类型:
INSERT INTO `table_name` (`location`) VALUES (POINT(-73.935242, 40.730610));
在这个例子中,我们在插入数据时直接将地理坐标添加到了location
字段中。由于该字段上已经创建了单列索引,因此可以对该坐标进行地理空间查询。
3)查询时使用单列索引(SPATIAL):
SELECT * FROM `table_name`
WHERE MBRContains(GeomFromText(
'POLYGON((-73.935242 -0.000000, -73.935242 0.000000,
-73.935242 10.000000, -73.935242 10.000000, -73.935242 -0.000000))'
), `location`);
在这个例子中,我们在查询条件中使用了MBRContains函数来进行地理空间查询。由于该字段上已经创建了单列索引,因此MySQL可以使用该索引来加速查询。
4)强制使用单列索引(SPATIAL):
SELECT * FROM `table_name` FORCE INDEX (`SPATIAL INDEX`)
WHERE MBRContains(GeomFromText(
'POLYGON((-73.935242 -0.000000,-73.935242 0.000000,
-73.935242 10.000000, -73.935242 10.000000,-73.935242 -0.000000))'
), `location`);
在这个例子中,我们使用了FORCE INDEX关键字来强制查询优化器使用名为SPATIAL INDEX
的单列索引进行查询。
这些示例展示了如何使用单列索引(SPATIAL)来进行地理空间查询并提高查询性能。在实际使用时,需要根据具体情况和需求选择合适的索引类型和列。
5.多列索引(SPATIAL)
多列索引(SPATIAL)是MySQL中一种用于地理空间数据类型的索引类型。以下是一些使用多列索引(SPATIAL)的示例:
1)创建表并添加地理空间数据类型:
CREATE TABLE `table_name` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`location` point NOT NULL, `name` varchar(255) NOT NULL,
PRIMARY KEY (`id`, `location`), SPATIAL INDEX (`location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
在这个例子中,我们为location
字段创建了一个名为SPATIAL INDEX
的多列索引。由于该字段上已经创建了多列索引,因此可以进行地理空间查询。
2)插入数据时添加地理空间数据类型:
INSERT INTO `table_name` (`location`, `name`)
VALUES (POINT(-73.935242, 40.730610), 'New York');
在这个例子中,我们在插入数据时直接将地理坐标和名称添加到了表中。由于该字段上已经创建了多列索引,因此可以对该坐标进行地理空间查询。
3)查询时使用多列索引(SPATIAL):
SELECT * FROM `table_name` WHERE MBRContains(
GeomFromText('POLYGON((-73.935242 -0.000000, -73.935242 0.000000,
-73.935242 10.000000, -73.935242 10.000000, -73.935242 -0.000000))'
), `location`);
在这个例子中,我们在查询条件中使用了MBRContains函数来进行地理空间查询。由于该字段上已经创建了多列索引,因此MySQL可以使用该索引来加速查询。
4)强制使用多列索引(SPATIAL):
SELECT * FROM `table_name`
FORCE INDEX (`SPATIAL INDEX`)
WHERE MBRContains(GeomFromText(
'POLYGON((-73.935242 -0.000000, -73.935242 0.000000,
-73.935242 10.000000, -73.935242 10.000000, -73.935242 -0.000000))'
), `location`);
在这个例子中,我们使用了FORCE INDEX关键字来强制查询优化器使用名为SPATIAL INDEX
的多列索引进行查询。
这些示例展示了如何使用多列索引(SPATIAL)来进行地理空间查询并提高查询性能。在实际使用时,需要根据具体情况和需求选择合适的索引类型和列。
6.哈希索引(HASH)
哈希索引是基于哈希表实现的一种索引类型,只有当查询条件精确匹配哈希索引中的所有列时,才能够使用到哈希索引。这种索引方式的时间复杂度近似为O(1),实际的时间复杂度与数据的哈希冲突率有关。而空间复杂度则为O(n),因为需要为每一个元素存储一次信息。值得注意的是,哈希索引不支持部分索引列匹配查找,例如,在(A, B)数据列上建立哈希索引,如果查询只有数据列A,则无法使用该索引。此外,哈希索引只支持等值比较查询,包括=、in()、<=>等操作。
以下是使用哈希索引的一些示例:
1)创建哈希索引:
CREATE INDEX hash_index ON table_name (column_name) USING HASH;
在这个例子中,我们在指定的列上创建了一个名为hash_index的哈希索引。
2)插入数据后创建哈希索引:
ALTER TABLE table_name ADD INDEX hash_index (column_name) USING HASH;
在这个例子中,我们在插入数据后添加了一个名为hash_index的哈希索引。
3)查询时使用哈希索引:
SELECT * FROM table_name WHERE column_name = 'value';
在这个例子中,我们在查询条件中使用了等于操作符来查询数据。由于该字段上已经创建了哈希索引,因此MySQL可以使用该索引来加速查询。
7.B树索引(BTREE)
B树索引,又被称为B-Tree索引,是一种自平衡的树形数据结构,主要用于加速对表中数据行的检索。这种索引方式将数据分散存储,以实现快速查找。
一个度为d的B-Tree,假设其索引有N个key,那么这棵树的高度h的上限可以通过公式logd ( (N+1)/2)logd ( (N+1)/2)来计算。当需要检索一个key时,其查找节点个数的渐进复杂度为O(logdN)。B-Tree索引中所有节点的子节点个数的最大值被称为B-树的阶,根据阶数的定义,m阶B-树最多有m个分支,根节点至少有2个分。
以下是使用B树索引的一些示例:
1)创建B树索引:
CREATE INDEX index_name ON table_name(column_name);
在这个例子中,我们在指定的列上创建了一个名为index_name的B树索引。
2)插入数据后创建B树索引:
ALTER TABLE table_name ADD INDEX index_name(column_name);
在这个例子中,我们在插入数据后添加了一个名为index_name的B树索引。
3)查询时使用B树索引:
SELECT * FROM table_name WHERE column_name = 'value';
在这个例子中,我们在查询条件中使用了等于操作符来查询数据。由于该字段上已经创建了B树索引,因此MySQL可以使用该索引来加速查询。
8.R树索引(RTREE)
R树,也叫R-tree,是一种空间索引数据结构,主要用于处理多维数据的空间查询问题。这种索引方式不仅可以加快数据检索速度,而且可以解决高维空间搜索等问题。
R树具有一些重要的特性:除根节点外,所有非根节点包含有m至M个记录索引(条目),而根节点的记录个数可以少于m。通常设定m=M/2。每一个非叶子节点的分支数和该节点内的条目数相同,一个条目对应一个分支。所有叶子节点都位于同一层,因此R树为平衡树。叶子节点的每一个条目表示一个点。非叶节点的每一个条目存放的数据结构为:(I,child−pointer)。child−pointer是指向该条目对应孩子节点的指针。I表示一个n维空间中的最小边界矩形MBR,I覆盖了该条目对应子树中所有的矩形或点。
以下是使用R树索引的一些示例:
-
创建RTree:可以使用静态构造方法 RTreeString, Geometry> tree = RTree.create(); 如果确定RTree存储的类型例如Point,则可以指定类型创建 RTreeString, Point> tree = RTree.create();。
-
添加结点到Rtree,需要指定该结点的平面位置或范围。
-
查询时使用R树索引:可以利用R树的独特性质进行各种复杂的空间查询,例如查找20英里以内所有的餐厅等。