Mysql建立、删除索引及使用( 三 )


mysql一张表查询只能用到一个索引 。因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的 。因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列建复合索引 。这一点是很多程序猿容易忽略的,如where子句的字段建了索引,排序的字段建了索引,但是分开建的,以为会走索引,其实这样的话排序的字段不会使用索引的,除非建复合索引,切记 。
4.like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,注意正确的使用方式 。like ‘%aaa%’不会使用索引,而like ‘aaa%’可以使用索引 。
5.不要在列上进行运算
6.不使用NOT IN 、<>、!=操作,但<,<=,=,>,>=,BETWEEN,IN是可以用到索引的
7.索引要建立在经常进行select操作的字段上 。
这是因为,如果这些列很少用到,那么有无索引并不能明显改变查询速度 。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求 。
8.索引要建立在值比较唯一的字段上 。
9.对于那些定义为text、image和bit数据类型的列不应该增加索引 。因为这些列的数据量要么相当大,要么取值很少 。
10.在where和join中出现的列需要建立索引 。
11.where的查询条件里有不等号(where column != …),mysql将无法使用索引 。
12.如果where字句的查询条件里使用了函数(如:where DAY(column)=…),mysql将无法使用索引 。
13.在join操作中(需要从多个数据表提取数据时),mysql只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了索引也不会使用 。
14.在进行联表查询时,建立关联的表的字段类型最好一样且长度一致,这样能更好的发挥索引的作用 。
15.组合索引时切记此条约束:组合索引中有多个字段,其中一个字段是有范围判断,则需将此字段在最后面 。如
ALTER TABLE USER_DEMO ADD INDEX name_age (NAME,AGE); 因为age会有范围判断,则建组合索引时将AGE字段放在后面 。
16.字符集字段比较,UTF8与UTF-BIN联合查询是不能走索引的 。
如某张表的order_no字段类型为varchar(50),另一张表的order_no字段类型为varchar(50) COLLATE utf8_BIN 。则此时联合查询时不能走索引的,切记 。
即两张表的字段类型如下:
`order_no` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '订单号',`order_no` varchar(50) NOT NULL DEFAULT '' COMMENT '订单号',17.以下几种情况不适合建索引:

  • 表记录太少
  • 经常插入、删除、修改的表
  • 数据重复且分布平均的表字段 。如一个表有10万行记录,其中字段column1只有A和B两种值,且每个值的分布概率大约为50%,那么对这种表column1字段建索引一般不会提高数据库的查询速度
18.给表创建主键,对于没有主键的表,在查询和索引定义上有一定的影响 。
19.避免表字段为null,建议设置默认值(如int类型设置默认值为0),这样在索引查询上,效率会高很多 。
建立索引的几大原则:
1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整 。2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大 。所以语句应该写成create_time = unix_timestamp(’2014-05-29’);5.尽量的扩展索引,不要新建索引 。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可



推荐阅读