zoukankan      html  css  js  c++  java
  • MySQL建立索引的注意事项

    对于大数据量的表格,尤其是百万行以上的数据表,一定要对其建立索引,否则查询速度极慢。(参考后面的测试结果)
    建立索引时需注意:

    MySQL的索引有两种:单列索引(即在某一列上建索引)、多列组合索引(即在多个列上建立同一个索引),不像SQL Server分聚集索引,非聚集索引。

    如何建立单列索引:

    格式:CREATE INDEX 索引名 on 表名(列名)

    例如:
    CREATE
    INDEX idx_geoinfo_tiny_cabid ON geoinfo_tiny (cabid)#创建一个名为idx_geoinfo_tiny_cabid的索引,该索引建立在geoinfo_tiny表上的cabid列上面

    如何建立多列组合索引:

    格式:CREATE INDEX 索引名 on 表名(列名1,列名2,列名3,...)

    例如: #创建一个名为idx_geoinfo_tiny_objectid_occupancy_time_cabid的索引,该索引建立在geoinfo_tiny表上的
    objectid,occupancy,occur_time,cabid等四个列上面
    CREATE
    INDEX idx_geoinfo_tiny_objectid_occupancy_time_cabid ON geoinfo_tiny (objectid,occupancy,occur_time,cabid)

    应该在哪个列上建立索引?建组合索引还是单列索引?

    先说第一问,应该在哪个列上建立索引?

    答:得根据自己的查询需求来,哪一列需要经常查询就在哪一列上建索引,一般是sql语句中where子句中的列,例如对于sql语句

    SELECT objectid,occur_time,latitude,longitude,cabid from geoinfo_tiny where cabid='afmorc' and time(occur_time)>time('07:00:00') and time(occur_time)<time('12:00:00')
    ORDER BY occur_time ASC

    where子句中作为判断依据的cabid列和time列,这两个列上应该建立索引。

    至于该建立组合索引还是单列索引,如不能确定,可以都试试,看哪个效果好。

    我本机上有一个表,名为geoinfo_tiny,6个字段,从.txt文件导入了2,867,457行数据(如何使用Python快速、大批量地导入数据,请看http://www.cnblogs.com/aaronhoo/p/5152292.html

    创建表:

    CREATE TABLE `geoinfo_tiny` (
    `objectid`  int(11) NOT NULL AUTO_INCREMENT ,
    `latitude`  double NOT NULL ,
    `longitude`  double NOT NULL ,
    `occupancy`  bit(1) NOT NULL ,
    `occur_time`  datetime NOT NULL ,
    `cabid`  varchar(16)

     待测试的查询语句:

    SELECT objectid,occur_time,latitude,longitude,cabid from geoinfo_tiny where cabid='afmorc' and time(occur_time)>time('07:00:00') and time(occur_time)<time('12:00:00')
    ORDER BY occur_time ASC

    测试1:不建立任何索引,直接查询

    结果:

    [SQL] SELECT objectid,occur_time,cabid from geoinfo_tiny where cabid='eckecky' and time(occur_time)>time('07:00:00') and time(occur_time)<time('12:00:00')
    ORDER BY occur_time ASC 

    受影响的行:
    0 时间: 4.254s

    测试2:只在cabid列上建立索引

    CREATE INDEX idx_geoinfo_tiny_cabid ON  geoinfo_tiny (cabid)

    结果:

    [SQL] SELECT objectid,occur_time,cabid from geoinfo_tiny where cabid='amwibs' and time(occur_time)>time('07:00:00') and time(occur_time)<time('12:00:00')
    ORDER BY occur_time ASC
    受影响的行: 0 时间: 0.147s

    测试3:只在occur_time列上建立索引

    CREATE INDEX idx_geoinfo_tiny_time ON  geoinfo_tiny (occur_time)

    结果:

    [SQL] SELECT objectid,occur_time,cabid from geoinfo_tiny where cabid='ancorjo' and time(occur_time)>time('07:00:00') and time(occur_time)<time('12:00:00')
    ORDER BY occur_time ASC
    
    受影响的行: 0
    时间: 4.668s

    测试4:在cabid、occur_time列上分别建立单列索引(此时该表上有2个单列索引)

    结果:

    [SQL] SELECT objectid,occur_time,cabid from geoinfo_tiny where cabid='atfrim' and time(occur_time)>time('07:00:00') and time(occur_time)<time('12:00:00')
    ORDER BY occur_time ASC
    
    受影响的行: 0
    时间: 0.195s

     测试5:在cabid、occur_time列上建立组合索引(此时该表上只有一个组合索引,没有单列索引)

     结果:最少0.038s,最多0.305s

     测试6:在cabid,occur_time,objectid,occupancy四个列上建立组合索引

     结果:4.249s-4.703s

    测试结果分析:

    对比测试1、测试2可知,建立索引之后查询速度大大提升。

    对比测试2、测试3可知,建立单列索引时,最好选择在int、float型等基本类型的列上建索引,若在复杂数据类型如datetime等列上,效果较差,和没建一样。

    对比测试2、测试4可知,增加单列索引并不一定能提高查询速度。

    对比测试2、4、5可知,组合索引比分别建两个单列索引似乎更有效。

    对比测试1、2、4、6可知,建组合索引时,并不是列越多越好,若与where子句无关的列参与进来会使得索引失去效果,甚至更糟。

    更多注意事项,请参考http://itindex.net/detail/54651-mysql-%E5%AD%A6%E4%B9%A0-%E7%B4%A2%E5%BC%95

  • 相关阅读:
    Java并发包中Lock的实现原理
    多线程---再次认识volatile,Synchronize,lock
    共享锁(S锁)和排它锁(X锁)
    Java 7中的TransferQueue 以及 SynchronousQueue
    精巧好用的DelayQueue
    非阻塞同步算法与CAS(Compare and Swap)无锁算法
    彻底理解线索二叉树
    使用import取代require
    子页面iframe跨域执行父页面定义的JS方法
    利用js实现 禁用浏览器后退
  • 原文地址:https://www.cnblogs.com/aaronhoo/p/5161376.html
Copyright © 2011-2022 走看看