mysql数据库怎么创建索引
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql数据库怎么创建索引相关的知识,希望对你有一定的参考价值。
普通索引 添加INDEXALTER TABLE `table_name` ADD INDEX index_name ( `column` )
下面演示下给user表的name字段添加一个索引
mysql数据库如何创建索引
mysql数据库如何创建索引
主键索引 添加PRIMARY KEY
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
mysql数据库如何创建索引
mysql数据库如何创建索引
唯一索引 添加UNIQUE
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
mysql数据库如何创建索引
全文索引 添加FULLTEXT
ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
mysql数据库如何创建索引
如何添加多列索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
mysql数据库如何创建索引 参考技术A
在满足语句需求的情况下,尽量少的访问资源是数据库设计的重要原则,这和执行的 SQL 有直接的关系,索引问题又是 SQL 问题中出现频率最高的,常见的索引问题包括:无索引(失效)、隐式转换。1. SQL 执行流程看一个问题,在下面这个表 T 中,如果我要执行 需要执行几次树的搜索操作,会扫描多少行?
这分别是 ID 字段索引树、k 字段索引树。
这条 SQL 语句的执行流程:
1. 在 k 索引树上找到 k=3,获得 ID=3002. 回表到 ID 索引树查找 ID=300 的记录,对应 R33. 在 k 索引树找到下一个值 k=5,ID=5004. 再回到 ID 索引树找到对应 ID=500 的 R4
5. 在 k 索引树去下一个值 k=6,不符合条件,循环结束
这个过程读取了 k 索引树的三条记录,回表了两次。因为查询结果所需要的数据只在主键索引上有,所以必须得回表。所以,我们该如何通过优化索引,来避免回表呢?2. 常见索引优化2.1 覆盖索引覆盖索引,换言之就是索引要覆盖我们的查询请求,无需回表。
如果执行的语句是 ,这样的话因为 ID 的值在 k 索引树上,就不需要回表了。
覆盖索引可以减少树的搜索次数,显著提升查询性能,是常用的性能优化手段。
但是,维护索引是有代价的,所以在建立冗余索引来支持覆盖索引时要权衡利弊。
2.2 最左前缀原则
B+ 树的数据项是复合的数据结构,比如 的时候,B+ 树是按照从左到右的顺序来建立搜索树的,当 这样的数据来检索的时候,B+ 树会优先比较 name 来确定下一步的检索方向,如果 name 相同再依次比较 sex 和 age,最后得到检索的数据。
可以清楚的看到,A1 使用 tl 索引,A2 进行了全表扫描,虽然 A2 的两个条件都在 tl 索引中出现,但是没有使用到 name 列,不符合最左前缀原则,无法使用索引。所以在建立联合索引的时候,如何安排索引内的字段排序是关键。评估标准是索引的复用能力,因为支持最左前缀,所以当建立(a,b)这个联合索引之后,就不需要给 a 单独建立索引。原则上,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。上面这个例子中,如果查询条件里只有 b,就是没法利用(a,b)这个联合索引的,这时候就不得不维护另一个索引,也就是说要同时维护(a,b)、(b)两个索引。这样的话,就需要考虑空间占用了,比如,name 和 age 的联合索引,name 字段比 age 字段占用空间大,所以创建(name,age)联合索引和(age)索引占用空间是要小于(age,name)、(name)索引的。
2.3 索引下推
以人员表的联合索引(name, age)为例。如果现在有一个需求:检索出表中“名字第一个字是张,而且年龄是26岁的所有男性”。那么,SQL 语句是这么写的
通过最左前缀索引规则,会找到 ID1,然后需要判断其他条件是否满足在 MySQL 5.6 之前,只能从 ID1 开始一个个回表。到主键索引上找出数据行,再对比字段值。而 MySQL 5.6 引入的索引下推优化(index condition pushdown),可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。这样,减少了回表次数和之后再次过滤的工作量,明显提高检索速度。
2.4 隐式类型转化
隐式类型转化主要原因是,表结构中指定的数据类型与传入的数据类型不同,导致索引无法使用。所以有两种方案:
修改表结构,修改字段数据类型。
修改应用,将应用中传入的字符类型改为与表结构相同类型。
3. 为什么会选错索引3.1 优化器选择索引是优化器的工作,其目的是找到一个最优的执行方案,用最小的代价去执行语句。在数据库中,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的 CPU 资源越少。当然,扫描行数并不是唯一的判断标准,优化器还会结合是否使用临时表、是否排序等因素进行综合判断。
3.2 扫描行数
MySQL 在真正开始执行语句之前,并不能精确的知道满足这个条件的记录有多少条,只能通过索引的区分度来判断。显然,一个索引上不同的值越多,索引的区分度就越好,而一个索引上不同值的个数我们称为“基数”,也就是说,这个基数越大,索引的区分度越好。
MySQL 使用采样统计方法来估算基数:采样统计的时候,InnoDB 默认会选择 N 个数据页,统计这些页面上的不同值,得到一个平均值,然后乘以这个索引的页面数,就得到了这个索引的基数。而数据表是会持续更新的,索引统计信息也不会固定不变。所以,当变更的数据行数超过 1/M 的时候,会自动触发重新做一次索引统计。
在 MySQL 中,有两种存储索引统计的方式,可以通过设置参数 innodb_stats_persistent 的值来选择:
on 表示统计信息会持久化存储。默认 N = 20,M = 10。
off 表示统计信息只存储在内存中。默认 N = 8,M = 16。
由于是采样统计,所以不管 N 是 20 还是 8,这个基数都很容易不准确。所以,冤有头债有主,MySQL 选错索引,还得归咎到没能准确地判断出扫描行数。
可以用 来重新统计索引信息,进行修正。
3.3 索引选择异常和处理1. 采用 force index 强行选择一个索引。2. 可以考虑修改语句,引导 MySQL 使用我们期望的索引。3. 有些场景下,可以新建一个更合适的索引,来提供给优化器做选择,或删掉误用的索引。
索引怎么建立使用
Sqlserver 中,有一张百万级的表,要 select * 去输出,如何建立索引和使用?
查所有字段去输出,索引要怎么建,在某几个字段上建立索引效率会有所提高吗?
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON <object> ( column [ ASC | DESC ] [ ,...n ] )
[ INCLUDE ( column_name [ ,...n ] ) ]
[ WHERE <filter_predicate> ]
[ WITH ( <relational_index_option> [ ,...n ] ) ]
[ ON partition_scheme_name ( column_name )
| filegroup_name
| default
]
[ FILESTREAM_ON filestream_filegroup_name | partition_scheme_name | "NULL" ]
参数
UNIQUE
为表或视图创建唯一索引。唯一索引不允许两行具有相同的索引键值。视图的聚集索引必须唯一。
无论 IGNORE_DUP_KEY 是否设置为 ON,数据库引擎都不允许为已包含重复值的列创建唯一索引。否则,数据库引擎会显示错误消息。必须先删除重复值,然后才能为一列或多列创建唯一索引。唯一索引中使用的列应设置为 NOT NULL,因为在创建唯一索引时,会将多个 Null 值视为重复值。
CLUSTERED
创建索引时,键值的逻辑顺序决定表中对应行的物理顺序。聚集索引的底层(或称叶级别)包含该表的实际数据行。一个表或视图只允许同时有一个聚集索引。
具有唯一聚集索引的视图称为索引视图。为一个视图创建唯一聚集索引会在物理上具体化该视图。必须先为视图创建唯一聚集索引,然后才能为该视图定义其他索引。
在创建任何非聚集索引之前创建聚集索引。创建聚集索引时会重新生成表中现有的非聚集索引。
如果没有指定 CLUSTERED,则创建非聚集索引。
注意:
因为按照定义,聚集索引的叶级别与其数据页相同,所以创建聚集索引和使用 ON partition_scheme_name 或 ON filegroup_name 子句实际上会将表从创建该表时所在的文件组移到新的分区方案或文件组中。对特定的文件组创建表或索引之前,应确认哪些文件组可用并且有足够的空间供索引使用。
NONCLUSTERED
创建一个指定表的逻辑排序的索引。对于非聚集索引,数据行的物理排序独立于索引排序。
无论是使用 PRIMARY KEY 和 UNIQUE 约束隐式创建索引,还是使用 CREATE INDEX 显式创建索引。每个表都最多可包含 999 个非聚集索引。
对于索引视图,只能为已定义唯一聚集索引的视图创建非聚集索引。
默认值为 NONCLUSTERED。
index_name
索引的名称。索引名称在表或视图中必须唯一,但在数据库中不必唯一。索引名称必须符合标识符的规则。
column
索引所基于的一列或多列。指定两个或多个列名,可为指定列的组合值创建组合索引。在 table_or_view_name 后的括号中,按排序优先级列出组合索引中要包括的列。
一个组合索引键中最多可组合 16 列。组合索引键中的所有列必须在同一个表或视图中。组合索引值允许的最大大小为 900 字节。
不能将大型对象 (LOB) 数据类型 ntext、text、varchar(max)、 nvarchar(max)、varbinary(max)、xml 或 image 的列指定为索引的键列。另外,即使 CREATE INDEX 语句中并未引用 ntext、text 或 image 列,视图定义中也不能包含这些列。
如果 CLR 用户定义类型支持二进制排序,则可以为该类型的列创建索引。另外,对于已定义为用户定义类型列的方法调用的计算列,只要这些方法标记为确定性方法且不执行数据访问操作,便可为该计算列创建索引。
[ ASC | DESC ]
确定特定索引列的升序或降序排序方向。默认值为 ASC。
INCLUDE ( column [ ,...n ] )
指定要添加到非聚集索引的叶级别的非键列。非聚集索引可以唯一,也可以不唯一。
在 INCLUDE 列表中列名不能重复,且不能同时用于键列和非键列。
除 text、ntext 和 image 之外,允许所有数据类型。如果指定的任一非键列属于 varchar(max)、nvarchar(max) 或 varbinary(max) 数据类型,则必须脱机 (ONLINE = OFF) 创建或重新生成该索引。
精确或不精确的确定性计算列都可以是包含列。从 image、ntext、text、varchar(max)、nvarchar(max)、varbinary(max) 和 xml 数据类型派生的计算列可以包含在非键列中,前提是允许将这些计算列数据类型作为包含列。
WHERE <filter_predicate>
通过指定索引中要包含哪些行来创建筛选索引。筛选索引必须是对表的非聚集索引。为筛选索引中的数据行创建筛选统计信息。
筛选谓词使用简单比较逻辑且不能引用计算列、UDT 列、空间数据类型列或 hierarchyID 数据类型列。比较运算符不允许使用 NULL 文本的比较。请改用 IS NULL 和 IS NOT NULL 运算符。
下面是 Production.BillOfMaterials 表的筛选谓词的一些示例:
WHERE StartDate > '20000101' AND EndDate <= '20000630'
WHERE ComponentID IN (533, 324, 753)
WHERE StartDate IN ('20000404', '20000905') AND EndDate IS NOT NULL
筛选索引不适用于 XML 索引和全文索引。对于 UNIQUE 索引,仅选定的行必须具有唯一的索引值。筛选索引不允许有 IGNORE_DUP_KEY 选项。
ON partition_scheme_name ( column_name )
指定分区方案,该方案定义要将分区索引的分区映射到的文件组。必须通过执行 CREATE PARTITION SCHEME 或 ALTER PARTITION SCHEME,使数据库中存在该分区方案。column_name 指定将作为分区索引的分区依据的列。该列必须与 partition_scheme_name 使用的分区函数参数的数据类型、长度和精度相匹配。column_name 不限于索引定义中的列。除了在对 UNIQUE 索引分区时,必须从用作唯一键的列中选择 column_name 外,还可以指定基表中的任何列。通过此限制,数据库引擎可验证单个分区中的键值唯一性。
注意:
在对非唯一的聚集索引进行分区时,如果尚未指定分区依据列,则默认情况下数据库引擎将在聚集索引键列表中添加分区依据列。在对非唯一的非聚集索引进行分区时,如果尚未指定分区依据列,则数据库引擎会添加分区依据列作为索引的非键(包含)列。
如果未指定 partition_scheme_name 或 filegroup 且该表已分区,则索引会与基础表使用相同分区依据列并被放入同一分区方案中。
有关将索引分区的详细信息,请参阅已分区索引的特殊指导原则。
ON filegroup_name
为指定文件组创建指定索引。如果未指定位置且表或视图尚未分区,则索引将与基础表或视图使用相同的文件组。该文件组必须已存在。
ON "default"
为默认文件组创建指定索引。
在此上下文中,“default”不是关键字。它是默认文件组的标识符,并且必须进行分隔(类似于 ON "default" 或 ON[default])。如果指定了 "default",则当前会话的 QUOTED_IDENTIFIER 选项必须为 ON。这是默认设置。
[ FILESTREAM_ON filestream_filegroup_name | partition_scheme_name | "NULL" ]
在创建聚集索引时,指定表的 FILESTREAM 数据的位置。FILESTREAM_ON 子句用于将 FILESTREAM 数据移动到不同的 FILESTREAM 文件组或分区方案。
filestream_filegroup_name 是 FILESTREAM 文件组的名称。该文件组必须包含一个使用 CREATE DATABASE 或 ALTER DATABASE 语句为该文件组定义的文件;否则,将引发错误。
如果表已分区,则必须包含 FILESTREAM_ON 子句并且必须指定 FILESTREAM 文件组的分区方案,且此分区方案需使用与该表分区方案相同的分区函数和分区列。否则将引发错误。
如果该表未分区,则无法对 FILESTREAM 列分区。该表的 FILESTREAM 数据必须存储在一个由 FILESTREAM_ON 子句指定的文件组中。
如果创建的是聚集索引且该表不包含 FILESTREAM 列,则可在 CREATE INDEX 语句中指定 FILESTREAM_ON NULL。 参考技术A 索引是以表列为基础的数据库对象,索引中保存着表中排序的索引列,并且纪录了索引列在数据库表中的物理存储位置,实现了表中数据的逻辑排序。
通过索引,可以加快数据的查询速度和减少系统的响应时间;
可以使表和表之间的连接速度加快。
用SQL建立索引:
为了给一个表建立索引,启动任务栏SQL Sever程序组中的ISQL/w程序。进入查询窗口后,输入下面的语句:
CREATE [UNIQUE] [CLUSER] INDEX <索引名> ON <表名> (<列名>);
UNIQUE 表明此索引的每一个索引值只对应唯一的数据记录
CLUSTER 表明要建立的是聚簇索引(指索引项的顺序与表中记录的物理顺序一致)
例:CREATE CLUSER INDEX Stuname ON Student(Sname);
在student表的sname列建立一个聚簇索引,student中记录按照sname值的升序排列. 参考技术B 如果你查询的字段都在索引中,那么可以只查询索引,不用查询表,就可以输出数据。
这是建索引时的一种考虑。
但是在你这种情况下不适用。
我猜你是想输出大批数据,而不是根据索引选择有数的那么几条。
输出数据占总数据量达到一定比例以后,再用索引就是浪费更多资源而得不到回报了。
因为数据行存储在块中。一块存多行。用索引时是根据索引信息,每一行访问一次数据块。
数据多了会覆盖大多数数据块,并且一个数据块会被访问多次。就不如全表扫描一次,访问一个数据块就把该块所有行都输出。这样效率最高。
所以你这种情况不应该用索引的。
以上是关于mysql数据库怎么创建索引的主要内容,如果未能解决你的问题,请参考以下文章