1索引类型UNIQUE唯一索引不能有相同的值,可以有NULL值。INDEX普通索引允许出现相同的索引内容。PRIMARYKEY主键索引不允许有相同的值,也不能为NULL值,一张表只能有一个primary_key索引。全文索引全文索引以上三个索引都是对列的值起作用的,但是全文索引可以针对值中的某个词,比如一篇文章中的某个词,但是没有用,因为只有myisam和英文支持,效率不敢恭维,不过可以使用coreseek、xunsearch等第三方应用来完成这个需求。2索引ALTERTABLE的CURD索引的创建适合在建表后添加。ALTERTABLEtablenameADDindextype(unique,primarykey,fulltext,index)索引名称ALTERTABLE`table_name`ADDINDEX`index_name`(`column_list`)--索引名称,可选;如果不是,则当前索引名称为字段名称。ALTERTABLE`table_name`ADDUNIQUE(`column_list`)ALTERTABLE`table_name`ADDPRIMARYKEY(`column_list`)ALTERTABLE`table_name`ADDFULLTEXTKEY(`column_list`)CREATEINDEXCREATEINDEX可以添加普通索引或UNIQUE索引到表。--例子:只能添加这两个索引CREATEINDEXindex_nameONtable_name(column_list)CREATEUNIQUEINDEXindex_nameONtable_name(column_list)另外,也可以在建表时添加:CREATETABLE`test1`(`id`smallint(5)UNSIGNEDAUTO_INCREMENTNOTNULL,--注意下面创建了主键索引,所以不需要创建`username`varchar(64)NOTNULLCOMMENT'username',`nickname`varchar(50)NOTNULLCOMMENT'nickname/name',`intro`text,PRIMARYKEY(`id`),UNIQUEKEY`unique1`(`username`),--索引名,可不可选,与列名KEY相同index1`(`nickname`),FULLTEXTKEY`intro`(`intro`))ENGINE=MyISAMAUTO_INCREMENT=4DEFAULTCHARSET=utf8COMMENT='backgroundusertable';deleteindexDROPINDEX`index_name`ON`talbe_name`ALTERTABLE`table_name`DROPINDEX`index_name`--这两句是等价的,都是删除table_name中的索引index_name;ALTERTABLE`table_name`DROPPRIMARYKEY--删除主键索引,注意只能通过这种方式删除主键索引seeshowindexfromtablename;索引的改变改变一个线程,删除并重建一个索引,可以创建一个具有高维列的索引。数据列中唯一值的个数,个数越大,维度越高。比如数据表中有8行数据a,b,c,d,a,b,c,d。这张表的维度是4,要为gender、age等高维的列创建索引,age的维度要高于gender。诸如性别之类的列不适合建立索引,因为它们的维度太低。对出现在where、on、groupby、orderby中的列使用索引。对较小的数据列使用索引,这将使索引文件更小,并且可以在内存中加载更多的索引键。对较长的字符串使用前缀索引。不要创建太多索引。除了增加额外的磁盘空间外,对DML操作的速度也会有很大的影响,因为每次添加或删除时,都必须重建索引。使用复合索引可以减小文件索引的大小,使用时比多个单列索引速度更快。4复合索引和前缀索引注意这两个名称是索引技术的名称,而不是索引的类型。复合索引MySQL单列索引和复合索引有什么区别?为了直观对比两者,先建表:CREATETABLE`myIndex`(`i_testID`INTNOTNULLAUTO_INCREMENT,`vc_Name`VARCHAR(50)NOTNULL,`vc_City`VARCHAR(50)NOTNULL,`i_Age`INTNOTNULL,`i_SchoolID`INTNOTNULL,PRIMARYKEY(`i_testID`));假设表中有1000条记录,在这10000条记录中,vc_Name=”erquan”的5条记录分布在7上8下,只是城市、年龄、学校的组合不同。看看这个T-SQL:SELECT`i_testID`FROM`myIndex`WHERE`vc_Name`='erquan'AND`vc_City`='Zhengzhou'AND`i_Age`=25;--协会搜索;首先考虑构建MySQL单列索引:在vc_Name列上创建索引。在执行T-SQL时,MYSQL很快将目标锁定在vc_Name=erquan这5条记录上,取出来放在一个中间结果集中。在这个结果集中,先排除vc_City不等于“郑州”的记录,再排除i_Age不等于25的记录,最后过滤掉唯一符合条件的记录。虽然在vc_Name上建立了索引,MYSQL在查询时不需要扫描整张表,效率有所提高,但离我们的要求还有一定的距离。同样,在vc_City和i_Age中建立MySQL单列索引的效率也差不多。为了进一步压榨MySQL的效率,需要考虑构建复合索引。就是把vc_Name,vc_City,i_Age建成索引:ALTERTABLE`myIndex`AD??DINDEX`name_city_age`(vc_Name(10),vc_City,i_Age);建表的时候,vc_Name的长度是50,这里为什么用10呢?这就是下面要说的前缀索引,因为一般名字的长度不会超过10,这样会加快索引查询速度,减小索引文件的大??小,增加INSERT的更新速度。执行T-SQL时,MySQL不需要扫描任何记录就可以找到唯一的记录!如果分别在vc_Name、vc_City、i_Age上创建单列索引,让表有3个单列索引,查询效率会不会和上述组合索引一样?答案截然不同,远低于我们的综合指数。此时虽然有3个索引,但是MySQL只能使用其中一个,貌似是单列索引效率最高的,另外两个没有用,也就是说还是全表的过程扫描。建立这样一个组合索引其实相当于建立三个组合索引:vc_Name、vc_City、i_Agevc_Name、vc_Cityvc_Name!为什么没有vc_City、i_Age等复合索引呢?这是mysql复合索引的“最左前缀”的结果。简单的理解就是只从最左边开始组合。不仅包含这三列的查询会使用这个复合索引,下面的T-SQL也会使用它:SELECT*FROMmyIndexWHREEi_Age=20ANDvc_City="郑州"SELECT*FROMmyIndexWHREEvc_City="郑州"即name_city_age(vc_Name(10),vc_City,i_Age)从左到右的索引,如果没有左前索引Mysql不会进行索引查询。前缀索引如果索引列的长度过长,这种列索引会生成一个很大的索引文件,不便于操作。您可以使用前缀索引方法来索引前缀索引。前缀索引要控制在一个合适的点,就是0.31gold是的(大于这个值可以创建)。从Arctic中选择COUNT(DISTINCT(LEFT(title,10)))/COUNT(*);—该值大于0.31创建前缀索引,重复ALTERTABLEuserADDINDEXuname(title(10));--增加PrefixindexSQL,name的索引建立在10,可以减小索引文件的大??小,加快索引查询。5什么样的sql不使用索引尽量避免这些sqlSELECT`sname`FROM`stu`W??HERE`age`+10=30;--不会使用索引,因为所有索引列都参与了SELECT的计算`sname`FROM`stu`W??HERELEFT(`date`,4)<1990;--不会使用索引,因为使用了函数操作,原理同上SELECT*FROM`houdunwang`WHERE`uname`LIKE'backing%'--取索引SELECT*FROM`houdunwang`WHERE`uname`LIKE"%backing%"--Donotusetheindex--正则表达式不使用索引,应该很容易理解,那为什么在SQL中很难看到regexp关键字的原因--字符串和数字不要使用索引;创建表`a`(`a`char(10));EXPLAINSELECT*FROM`a`WHERE`a`="1"--获取索引EXPLAINSELECT*FROM`a`WHERE`a`=1--不要使用索引select*fromdeptwheredname='xxx'或者loc='xx'ordeptno=45--如果条件中有or,即使条件中有index也不会用。换句话说,所有需要使用的字段都必须被索引。我们建议您尽可能避免使用or关键字——如果mysql估计使用全表扫描比使用索引更快,那么就不要使用索引。多表关联时的索引效率SELECT`sname`FROM`stu`W??HERELEFT(`date`,4)<1990;--不会使用索引,因为使用了函数操作,原理同上SELECT*FROM`houdunwang`WHERE`uname`LIKE'backing%'--取索引SELECT*FROM`houdunwang`WHERE`uname`LIKE"%backing%"--不使用索引从上图可以看出,所有表的类型都是all,也就是全表索引。即666,一共遍历了216条查询。除了第一个代表全表索引(必须的,必须关联其他表),其余都是范围(从索引区间获取),即6+1+1+1,一共是9个遍历查询就够了。因此,我们建议您在连接多个表时,连接的表越少越好,因为如果您不小心,这将是一次可怕的笛卡尔积扫描。另外,我们也建议尽量使用leftjoin,以少关联多。因为如果使用join的话,必须对第一个表进行全扫描,通过lessassociation和more可以减少扫描次数。6索引的缺点不要盲目创建索引,只为查询操作频繁的列创建索引。创建索引会使查询操作变快,但会减慢增删改操作的速度,因为这些操作会同时执行重新排序或更新索引文件。但是在互联网应用中,查询语句比DML语句大很多,甚至可以占到80%~90%,所以不用太在意,但是在导入大数据的时候,可以删除索引首先,然后批量插入数据。最后添加索引。
