zoukankan      html  css  js  c++  java
  • MySQL使用索引的问题

    使用索引的问题

    设计好MySql的索引可以让你的数据库飞起来,大大的提高数据库效率。

    但是你设计了索引就一定会用到码?索引就不会给你带来一些问题吗?

    设计MySql索引的时候有一下几点注意:

    1、创建索引

    对于 查询占主要 的应用来说,索引显得尤为重要。很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或者说没有添加更为有效的索引导致。如果不加索引的话,那么查找任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下降。但是也不是什么情况都非得建索引不可,比如性别可能就只有两个值,建索引不仅没什么优势,还会影响到更新速度,这被称为过度索引。

    (1)哪些情况下适合建索引
    1. 频繁作为where条件语句查询的字段

    2. 关联字段需要建立索引,例如外键字段,student表中的classid, classes表中的schoolid 等

    3. 排序字段可以建立索引

    4. 分组字段可以建立索引,因为分组的前提是排序

    5. 统计字段可以建立索引,例如count(),max()

    (2)哪些情况下不适合建索引

    1.频繁更新的字段不适合建立索引

    2.where条件中用不到的字段不适合建立索引

    3.表数据可以确定比较少的不需要建索引

    4.数据重复且发布比较均匀的的字段不适合建索引(唯一性太差的字段不适合建立索引),例如性别,真假值

    假如索引列TYPE有5个键值,如果有1万条数据,那么 WHERE TYPE = 1将访问表中的2000个数据块。再加上访问索引块,一共要访问大于200个的数据块。如果全表扫描,假设10条数据一个数据块,那么只需访问1000个数据块,既然全表扫描访问的数据块少一些,肯定就不会利用索引了。

    1. 参与列计算的列不适合建索引,索引会失效
    2、习惯使用复合索引

    比如有一条语句是这样的:select * from users where area=’beijing’ and age=22;

    如果我们是在area和age上分别创建单个索引的话,由于mysql查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效率,但是如果在area、age两列上创建复合索引的话将带来更高的效率。如果我们创建了(area, age,salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀特性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。

    3、索引不会包含有NULL值的列

    a.单列索引无法储null值,复合索引无法储全为null的值。

    b.查询时,采用is null条件时,不能利用到索引,只能全表扫描。

    为什么索引列无法存储Null值?

    a.索引是有序的。NULL值进入索引时,无法确定其应该放在哪里。(将索引列值进行建树,其中必然涉及到诸多的比较操作,null 值是不确定值无法比较,无法确定null出现在索引树的叶子节点位置。)

    b.如果需要把空值存入索引,方法有二:其一,把NULL值转为一个特定的值,在WHERE中检索时,用该特定值查找。其二,建立一个复合索引。例如

    create index ind_a on table(col1,1); 通过在复合索引中指定一个非空常量值,而使构成索引的列的组合中,不可能出现全空值。

    4,使用短索引

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

    5,排序的索引问题

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

    6、MySQL索引失效的几种情况
    • 如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
    • 复合索引不满足最左原则就不能使用索引
    • like查询以%开头
    • 如果mysql估计使用全表扫描要比使用索引快,则不使用索引
    5.MySQL主要提供2种方式的索引:B-Tree索引,Hash索引

    B树索引具有范围查找和前缀查找的能力,对于有N节点的B树,检索一条记录的复杂度为O(LogN)。相当于二分查找。

    哈希索引只能做等于查找,但是无论多大的Hash表,查找复杂度都是O(1)。

    显然,如果值的差异性大,并且以等值查找(=、 <、>、in)为主,Hash索引是更高效的选择,它有O(1)的查找复杂度。

    如果值的差异性相对较差,并且以范围查找为主,B树是更好的选择,它支持范围查找。

  • 相关阅读:
    hdoj 3599 最小费用最大流
    poj 2516 最小费用最大流
    poj 3281 最大流拆点
    poj 3436 网络最大流加打印路径
    邻接表模板
    hdu 2102 搜索
    hdoj 1533 最小费用最大流
    HDU 1231 最大连续子序列
    NYOJ 2 括号配对问题
    POJ 1163 / NYOJ 16 The Triangle(数字三角形)
  • 原文地址:https://www.cnblogs.com/jinronga/p/14579185.html
Copyright © 2011-2022 走看看