一,什么情况下使用索引

1. 表的主关键字

自动建立唯一索引

2. 表的字段唯一约束

ORACLE利用索引来保证数据的完整性

3. 直接条件查询的字段

在SQL中用于条件约束的字段

如zl_yhjbqk(用户基本情况)中的qc_bh(区册编号)

select * from zl_yhjbqk where qc_bh=’7001’;

4. 查询中与其它表关联的字段

字段常常建立了外键关系

如zl_ydcf(用电成份)中的jldb_bh(计量点表编号)

select * from zl_ydcf a,zl_yhdb b where a.jldb_bh=b.jldb_bh and b.jldb_bh=’540100214511’;

5. 查询中排序的字段

排序的字段如果通过索引去访问那将大大提高排序速度

select * from zl_yhjbqk order by qc_bh(建立qc_bh索引);select * from zl_yhjbqk where qc_bh=’7001’ order by cb_sx(建立qc_bh+cb_sx索引,注:只是一个索引,其中包括qc_bh和cb_sx字段);

6. 查询中统计或分组统计的字段

select max(hbs_bh) from zl_yhjbqk;select qc_bh,count(*) from zl_yhjbqk group by qc_bh;

二,什么情况下应不建或少建索引

1. 表记录太少

如果一个表只有5条记录,采用索引去访问记录的话,那首先需访问索引表,再通过索引表访问数据表,一般索引表与数据表不在同一个数据块,这种情况下ORACLE至少要往返读取数据块两次。而不用索引的情况下ORACLE会将所有的数据一次读出,处理速度显然会比用索引快。

如表zl_sybm(使用部门)一般只有几条记录,除了主关键字外对任何一个字段建索引都不会产生性能优化,实际上如果对这个表进行了统计分析后ORACLE也不会用你建的索引,而是自动执行全表访问。如:

select * from zl_sybm where sydw_bh=’5401’(对sydw_bh建立索引不会产生性能优化)

2. 经常插入、删除、修改的表

对一些经常处理的业务表应在查询允许的情况下尽量减少索引,如zl_yhbm,gc_dfss,gc_dfys,gc_fpdy等业务表。

3. 数据重复且分布平均的表字段

假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一般不会提高数据库的查询速度。

4. 经常和主字段一块查询但主字段索引值比较多的表字段

如gc_dfss(电费实收)表经常按收费序号、户标识编号、抄表日期、电费发生年月、操作 标志来具体查询某一笔收款的情况,如果将所有的字段都建在一个索引里那将会增加数据的修改、插入、删除时间,从实际上分析一笔收款如果按收费序号索引就已 经将记录减少到只有几条,如果再按后面的几个字段索引查询将对性能不产生太大的影响。


三、MySQL索引的概念

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。上述SQL语句,在没有索引的情况下,数据库会遍历全部200条数据后选择符合条件的;而有了相应的索引之后,数据库会直接在索引中查找符合条件的选项。如果我们把SQL语句换成“SELECT * FROM article WHERE id=2000000”,那么你是希望数据库按照顺序读取完200万行数据以后给你结果还是直接在索引中定位呢?(注:一般数据库默认都会为主键生成索引)。

索引分为聚簇索引和非聚簇索引两种,聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。

四、索引的类型

在数据库表中,对字段建立索引可以大大提高查询速度。假如我们创建了一个 mytable表

代码如下:

CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT
NULL );

我们随机向里面插入了10000条记录,其中有一条:5555, admin。

在查找username="admin"的记录 SELECT * FROM mytable WHERE
username=‘admin’;时,如果在username上已经建立了索引,MySQL无须任何扫描,即准确可找到该记录。相反,MySQL会扫描所有记录,即要查询10000条记录。

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索包含多个列。

1、普通索引
这是最基本的索引,它没有任何限制,比如上文中为title字段创建的索引就是一个普通索引,MyIASM中默认的BTREE类型的索引,也是我们大多数情况下用到的索引。
创建方式:

  • 直接创建索引
CREATE INDEX index_name ON table(column(length));
  • 修改表结构的方式添加索引
ALTER TABLE table_name ADD INDEX index_name ON (column(length));
  • 创建表的时候同时创建索引
CREATE TABLE `table` (`id` int(11) NOT NULL AUTO_INCREMENT ,`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,`time` int(10) NULL DEFAULT NULL ,PRIMARY KEY (`id`),INDEX index_name (title(length))
);
  • 删除索引
DROP INDEX index_name ON table;

2、唯一索引
与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须是唯一的,创建方法和普通索引类似。

  • 创建唯一索引
CREATE UNIQUE INDEX index_name ON table(column(length));
  • 修改表结构
ALTER TABLE table_name ADD UNIQUE INDEX index_name ON (column(length));
  • 创建表时同时创建索引
CREATE TABLE `table` (`id` int(11) NOT NULL AUTO_INCREMENT ,`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,`time` int(10) NULL DEFAULT NULL ,PRIMARY KEY (`id`),UNIQUE indexName (title(length))
);

3、主键索引
它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引:

// 代码如下:
CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL,   PRIMARY KEY(ID)   );

当然也可以用 ALTER 命令。记住:一个表只能有一个主键。

4、组合索引
平时用的SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引。
例如上表中针对title和time建立一个组合索引:

ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10));

建立这样的组合索引,其实是相当于分别建立了下面两组组合索引:

–title,time–title

为什么没有time这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。
简单的理解就是只从最左面的开始组合。并不是只要包含这两列的查询都会用到该组合索引,如下面的几个SQL所示:

  • 使用到上面的索引
SELECT * FROM article WHREE title='测试' AND time=1234567890;SELECT * FROM article WHREE utitle='测试';
  • 未使用到上面的索引
SELECT * FROM article WHREE time=1234567890;

五、索引的优化

上面说了使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。下面是一些总结以及收藏的MySQL索引的注意事项和优化方法。

1. 何时使用聚集索引或非聚集索引?

事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。

2. 索引不会包含有NULL值的列

只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

3. 使用短索引

对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

4. 索引列排序

MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

5. like语句操作

一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

6. 不要在列上进行运算

//例如:
select * from users where YEAR(adddate)<2007;

将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:

select * from users where adddate<’2007-01-01′;

关于这一点可以围观:一个单引号引发的MYSQL性能损失。

最后总结一下,MySQL只对以下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些时候的like(不以通配符%或_开头的情形)。
而理论上每张表里面最多可创建16个索引,不过除非是数据量真的很多,否则过多的使用索引会引起反作用,索引虽好用,可不要太迷恋噢。


原文链接:

转自:https://www.cnblogs.com/Adalia-Ting/p/9492475.html
https://blog.csdn.net/dengchenrong/article/details/88425762

关于MySQL什么时候使用索引 什么情况下应不建或少建索引相关推荐

  1. mysql基础14(关于mysql数据库在没有主键情况下去除重复数据办法)

    关于mysql数据库在没有主键情况下去除重复数据办法 约定 表名:mat 根据 cat 字段去重 新增加主键为 id 步骤 1.为mat新增一列自增主键 alter table mat add col ...

  2. MySQL为什么在使用索引的情况下能够提高查询效率,不使用索引又会是什么情形

    先来个生活学习中直观的体验--查字典 字典都有拼音.偏旁部首或者笔画数三个供检索的部分. 它们能以不同的方式快速定位到某个字词在哪一页. 而且存放这些索引部分的地方很好找,不是字典后面,就是字典前面. ...

  3. mysql update 负数_解决并发情况下库存减为负数问题--update2016.04.24

    场景: 一个商品有库存,下单时先检查库存,如果>0,把库存-1然后下单,如果<=0,则不能下单,事务包含两条sql语句: select quantity from products WHE ...

  4. 个人计算机分为桌面计算机和便携式计算机,在选择传动方案时,只有为了传动布置或其它必要时才选用锥齿轮,一般情况下应尽量选用圆柱齿轮...

    参考答案如下 选择传只置或锥齿[单选题]冰中下锚时,应选择__. 几年前显卡都使用AGP作为与北桥芯片之间的接口,动方动布但现在越来越多的显卡开始采用性能更好的_____接口. [填空题]用户可以根据 ...

  5. mysql回表_到底什么情况下mysql innodb会发生回表操作?

    谢邀 MySQL innodb的主键索引是簇集索引,也就是索引的叶子节点存的是整个单条记录的所有字段值,不是主键索引的就是非簇集索引,非簇集索引的叶子节点存的是主键字段的值.回表是什么意思?就是你执行 ...

  6. 什么情况下应不建或少建索引

    1.表记录太少 2.经常插入.删除.修改的表 3.数据重复且分布平均的表字段,假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一般不会提 ...

  7. mysql在没有任何用户的情况下,如何恢复

    为什么80%的码农都做不了架构师?>>>    修改my.cnf配置文件(Linux: /etc/my.cnf)- 在[mysqld]域下添加 skip-grant-tables 2 ...

  8. 存款人在哪些情况下应向开户银行提出撤销银行结算账户的申请?

    撤销账户是指存款人因开户资格或其他原因被终止银行结算账户使用的行为.存款人(1)被撤并.解散.宣告破产或关闭的.(2)注销.被吊销营业执照的.(3)因迁址需要变更开户银行的.(4)其他原因需要撤销银行 ...

  9. 22-08-25 MySQL高级(03)MySQL索引、索引演绎、适合加索引的情况、执行计划Explain各字段解释

    "系统,那如果我没有绑定,没有简化,我原先的人生最大的可能是怎么样的",李长生好奇一问.很快系统给出了答案. "如果宿主是小说主角的话,就活个几章" " ...

最新文章

  1. 无副作用、效果超越吗啡!用微电极精准管理大脑“疼痛中心”,科学家探索止痛新方法...
  2. 免费教材丨第47期:业界大牛中文教学视频《深度学习:进阶》第21-24讲
  3. (十二)struts2的类型转换
  4. koa --- seesion实现登录鉴权
  5. win10改成ubundu主题_如何将ubuntu引导win10,修改为win10引导ubuntu
  6. 我的世界java 内存_我的世界如何分配内存
  7. HTML+CSS+JS实现 ❤️经典霓虹灯英文字母特效❤️
  8. 奥斯卡“最佳国际电影”奖,《哪吒之魔童降世》申请出战!
  9. redis 设置密码 和 redis.config文件
  10. 联想(ThinkServer) RD650做硬件 raid5 配置
  11. 如何在VLC中添加字幕?
  12. 百度有啊 真的还有啊
  13. 十二烷基-β-D-麦芽糖苷/CAS号: 69227-93-6
  14. 关于透明图像的滤色处理要注意的几个点
  15. Oracle-使用XTTS方式迁移11G到PDB数据库
  16. es-Ingest pipelines
  17. 4k分辨率是多少(真4k与假4k区别)
  18. 计算机专业山东省内大学排名,山东计算机科学与技术专业大学排名 2020年省内录取分数线...
  19. 如何理解yield的用法
  20. ExtJs 第二章,Ext.form.Basic表单操作

热门文章

  1. matlab yuy2转rgb,YUY2转RGB(或BGR)
  2. medcalc app android,医学计算APP
  3. i18n和i10n:国际化本地化
  4. java手机号判断运营商_根据手机号 判断省份和运营商
  5. 音频编解码G.711 G.729 G.723带宽问题
  6. centos8 yum 安装mysql8
  7. python 接口传递参数params | data | json
  8. linux中zip文件编码错误,解决linux下zip文件解压乱码问题
  9. 2021年中国半导体设备封装与测试市场趋势报告、技术动态创新及2027年市场预测
  10. 怀旧服大脚插件未能从服务器,大脚插件问题