关于mysql 索引自动优化机制: 索引选择性(Cardinality:索引基数)

1、两个同样结构的语句一个没有用到索引的问题:

查1到20号的就不用索引,查1到5号的就用索引,为什么呢?不稳定?

mysql> explain select * from test where f_submit_time between ‘2009-09-01‘ and ‘2009-09-20‘ \G;

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: test

type: ALL

possible_keys: PRIMARY,submit_time_index

key: NULL

key_len: NULL

ref: NULL

rows: 365628

Extra: Using where

1 row in set (0.02 sec)

mysql> explain select * from test where f_submit_time between ‘2009-09-01‘ and ‘2009-09-5‘ \G;

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: test

type: range

possible_keys: PRIMARY,submit_time_index

key: submit_time_index

key_len: 8

ref: NULL

rows: 52073

Extra: Using where

1 row in set (0.00 sec)

说明:

二叉树索引本来最适合的就是点查询,和小范围的range查询,

当预估返回的数据量超过一定比例( 貌似当预估的查询量达到总量的30% )的时候,

再根据索引一条一条去查就慢了,反而不如全表扫描快了。Mysql有自己内部自动优化机制,

但有些自动优化机制可能不是最优的。这时候就需要人工去干预。

比如长期不优化表,Mysql判断出索引不优,就会不使用索引。

有时候就要人工强制使用真正高效的索引(FORCE INDEX)。

其实当本身的查询就约等于一个全表查询的时候,强不强制使用索引基本上没什么效果。

2、再看个例子:

今天遇到一个奇怪的问题,明明已经建立了索引,select语句的explain也表明会利用这个索引,可是结果偏偏没有用索引,最后扫描了全表。
    两个结构完全一样的sql语句:

sql1: select * from table where col_a = 123 and col_b in (‘foo’,\‘bar’) order by id desc;

sql2: select * from table where col_a = 456 and col_b in (‘foo’,\‘bar’) order by id desc;

结果sql1选择利用了col_a的索引,速度很快,sql2利用了主键ID的索引,扫描了全表(40w行)。
    仔细分析,发现数据库中,col_a=456的记录数有近1万条,而col_a=123的记录数只有几条。
    于是就清楚了,MySQL选择索引不仅仅依据查询结构和索引结构,还会根据索引大概估算选择每种索引的数据量,然后选择他认为最快的索引。
    可能是主键索引会比普通index更快,所以mysql最后选择了数据量跟大的id索引。
    那么,如何解决这个问题呢?
     很简单,只要在order语句里写多个键即可,比如:order by col_a, id desc

REF:mysql查询中利用索引的机制  http://blogread.cn/it/article/5023?f=wb

3、本质原因:Cardinality(索引基数)

很关键的一个参数,平均数值组=索引基数/表总数据行,平均数值组越接近1就越有可能利用索引。

索引选择性是不重复的索引值也叫基数(cardinality)表中数据行数的比值,索引选择性=基数/数据行,基数可以通过“show index from 表名”查看。   
高索引选择性的好处就是mysql查找匹配的时候可以过滤更多的行,唯一索引的选择性最佳,值为1。

4、关于 mysql 索引优化与使用请见:

由浅入深探究mysql索引结构原理、性能分析与优化

http://my.oschina.net/leejun2005/blog/73912

时间: 2024-10-31 13:10:57

关于mysql 索引自动优化机制: 索引选择性(Cardinality:索引基数)的相关文章

sql学习笔记(15)-----------MySQL 索引与优化总结

索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点. 考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将对整个表进行扫描,最坏的情况下,如果所有数据页都不在内存,需要读取10^4个页面,如果这10^4个页面在磁盘上随机分布,需要进行10^4次I/O,假设磁盘每次I/O时间为10ms(忽略数据传输时间),则总共需要100s(但实际上要好很多很多).如果对之建立B-Tree索引,则只需要进行log100(10^6

理解MySQL——索引与优化

转自:理解MySQL——索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将对整个表进行扫描,最坏的情况下,如果所有数据页都不在内存,需要读取10^4个页面,如果这10^4个页面在磁盘上随机分布,需要进行10^4次I/O,假设磁盘每次I/O时间为10ms(忽略数据传输时间),则总共需要100s(但实际上要好很多很多).如果对之建立B-Tr

理解MySQL——索引与优化(转)

理解MySQL--索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将对整个表进行扫描,最坏的情况下,如果所有数据页都不在内存,需要读取10^4个页面,如果这10^4个页面在磁盘上随机分布,需要进行10^4次I/O,假设磁盘每次I/O时间为10ms(忽略数据传输时间),则总共需要100s(但实际上要好很多很多).如果对之建立B-Tree索

mysql性能优化-索引与优化

http://hongge.blog.51cto.com/ 一.MySQL性能优化之-影响性能的因素 1.商业需求的影响 不合理需求造成资源投入产出比过低,这里我们就用一个看上去很简单的功能来分析一下. 需求:一个论坛帖子总量的统计,附加要求:实时更新 从功能上来看非常容易实现,执行一条SELECT COUNT(*) from 表名 的Query 就可以得到结果.但是,如果我们采用不是MyISAM 存储引擎,而是使用的Innodb 的存储引擎,那么大家可以试想一下,如果存放帖子的表中已经有上千万

MySQL 性能优化---索引及优化

博主QQ:819594300 博客地址:http://zpf666.blog.51cto.com/ 有什么疑问的朋友可以联系博主,博主会帮你们解答,谢谢支持! 一.MySQL性能优化之-影响性能的因素 1.商业需求的影响 Myisam存储引擎内置一个计数器,count(*)时直接从计数器读取:而通过innodb存储引擎查找某个数据时,是必须扫描全表的,所以当执行对表的统计(即使用count(*)函数)时,myisam要比innodb要快的很多.所以一般在innodb上执行count(*)时一般要

mysql索引以及优化

今天看到别人写的一些关于mysql索引的文章,有一些小收获,就以此开启我的随笔记录简单摘了一些重点 转载文章:http://www.cnblogs.com/tgycoder/p/5410057.html mysql索引实现原理 1. MyISAM引擎使用B+Tree作为索引结构,叶结点的data域存放的是数据记录的地址,MyISAM的索引方式也叫做"非聚集"的,之所以这么称呼是为了与InnoDB的聚集索引区分. 2. InnoDB也使用B+Tree作为索引结构,第一个重大区别是Inno

MySql存储引擎+表解压缩机制+索引+查询缓存机制+慢查询日志

一.大型网站优化之MySql优化 1.优化和不优化的对比的 在业界当中我们有一个叫大数据(big data)的概念,所谓的大数据指代千万级别以上的数据作为起步的数据.所以我们现在需要对两张都具有50331650条记录的表进行查询对比,其中表名为tbl_no的表是没有做过任何优化手段的表,表名为tbl_yes的表是做过优化手段的表.这个实验的目的是观察具有优化手段和不具有优化手段的查询中速度的差别. 实验条件: 1)两张表的数据记录总数是相同的 2)两张表的数据字段结构也是一样的 3)查询的记录的

MySQL 千万 级数据量根据(索引)优化 查询 速度

一.索引的作用 索引通俗来讲就相当于书的目录,当我们根据条件查询的时候,没有索引,便需要全表扫描,数据量少还可以,一旦数据量超过百万甚至千万,一条查询sql执行往往需要几十秒甚至更多,5秒以上就已经让人难以忍受了. 提升查询速度的方向一是提升硬件(内存.cpu.硬盘),二是在软件上优化(加索引.优化sql:优化sql不在本文阐述范围之内). 能在软件上解决的,就不在硬件上解决,毕竟硬件提升代码昂贵,性价比太低.代价小且行之有效的解决方法就是合理的加索引. 索引使用得当,能使查询速度提升上万倍,效

MySQL 高级知识(索引、优化)

MySQL体系架构 连接池组件.管理服务和工具组件.SQL接口组件.查询分析器组件.优化器组件.缓冲组件.插件式存储引擎.物理文件:1.连接层:主要完成一些类似于连接处理,授权认证及相关的方案:2.服务层:主要完成大多数核心服务功能:3.引擎层:负责MySQL中数据的存储和提取,服务器通过API与存储引擎进行通信:注:储存引擎式基于表的,而不是数据库的: MySQL存储引擎InnoDB 和 MyISAM区别:1.InnoDB支持主外键.事务:2.InnoDB是行锁,操作时候只锁一行数据,适合高并