基于Python的数据分析:数据库索引效率探究
索引在数据库中是一个很特殊的存在,它的目的就是为了提高数据查询得效率。同样,它也有弊端,更新一个带索引的表的时间比更新一个没有带索引的时间更长。有得有失。我希望做一些研究测试,搞清楚索引对于我们使用数据库有什么影响,以及如何控制这个影响。
先简单介绍两个相对立的概念:聚集索引和非聚集索引。
聚集索引根据数据行的键值在表或视图中排序和存储这些数据行。索引定义中包含聚集索引列。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序排序。只有当表包含聚集索引时,表中的数据行才按排序顺序存储。如果表具有聚集索引,则该表称为聚集表。如果表没有聚集索引,则其数据行存储在一个称为堆的无序结构中。聚集索引特殊的方面是:聚集索引的叶级是实际的数据-也就是说,数据重新排序,按照和聚集索引排序条件声明的相同物理顺序存储。这意味着,一旦到达索引的叶级,就到达了数据。而非聚集索引,到达了叶级只是找到了数据的引用。因此聚集索引带来的空间消耗是需要额外的120%的空间。任何新记录都根据聚集列正确的物理顺序插入到聚集索引中。创建新页的方式随需要插入记录的位置而变化。如果新记录需要插入到索引结构中间,就会发生正常的页拆分。来自旧页的后一半记录被移到新页,并且在适当的时候,将新记录插入到新页或旧页。如果新记录在逻辑上位于索引结构的末端,那么创建新页,但是只将新记录添加到新页。在MySQL中,聚集索引可以认为是唯一索引。
非聚集索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。对于非聚集索引,可以为在表非聚集索引中查找数据时常用的每个列创建一个非聚集索引。非聚集索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。对于非聚集索引,可以为在表非聚集索引中查找数据时常用的每个列创建一个非聚集索引。在MySQL中,费聚集
引用一下网上常见的使用聚集索引和非聚集索引的使用上的注意事项:

本文并非探索索引的数据结构以及不同数据库的索引区别,对于数据分析而言也不是很重要,关键是搞懂索引的作用、索引的区别以及怎样使用索引。本文下面不再展开讨论索引的实现,对于索引结构及工作原理感兴趣的请看这篇文档http://www.cnblogs.com/kissdodog/archive/2013/06/12/3132380.html 。
测试环境和数据
不介绍测试环境的探究都是耍流氓,下面介绍一下测试所使用的环境和数据。
机器是两台IBM的PC,一台作为client,一台作为data server。PC的硬件是I5-4590CPU 3.3GHz+4GRAM(client),I7-4790 3.6GHZ+8GRAM(server)。client和server内网连接。client是win7 32位,server是win7 64位操作系统。
测试的数据库分别是MS SQLServer 2008R2版本 和 MySQL Server5.5版本。
分别再MySQL和SQLServer的测试数据库建了三个表student_no(无索引),student_in(有非聚集索引),student_cin(有聚集索引),表的字段都是一致的,参考下面的建表sql。
CREATE TABLE `student_xx` (
`ID` int(11) NOT NULL,
`name` varchar(10) NOT NULL,
`age` int(3) NOT NULL,
`address` varchar(10) NOT NULL
)
注意建表的过程中,我默认有几个设置,ID是所有数据都不一样的,是唯一标识符,name基本上所有人也不一样,age的数据比较一致在[20,30]这个区间,addres只记录所在省份城市的名字,数据范围在300个以内。
测试结果
测试使用的手段无非是对数据库的增删改查操作(where语句包含对应聚集索引和非聚集索引的),但是也有细分,我这里进行详细的定义。
插入操作:I1: 逐条插入,类似insert into student (ID, name,age,address) values(10000001,‘HE KEJUN’,28,’GUANGDONGG-GUANGZHOU’),每插入100条记录并记录耗时; I2:批量插入,即10次每次进行插入100条记录。
修改操作:U1:修改某个字段;U2:修改多个字段。每修改100条记录并记录耗时
删除操作:D1:删除某条记录(含where语句)。每删除100条记录并记录耗时。
查询操作:S1:查询数据;S2:查询中带有COUNT函数;S3查询中带有SUM函数;S4查询中带有ORDER BY。上述操作都是每查询1000条记录并记录耗时。
我们首先看看在小数量级的数据中索引的不同表现。
在小数据集(数据表记录数=10000)的情况下,各个数据库操作的耗时如下:
| MSSQL | MYSQL | |||||
| 无索引 | 非聚集索引 | 聚集索引 | 无索引 | 非聚集索引 | 聚集索引 | |
| I1 | 0.80935 | 0.81045 | 0.8031 | 1.07525 | 0.782 | 0.79005 |
| I2 | 2.1868 | 2.1891 | 2.13555 | 0.15565 | 0.1688 | 0.1478 |
| D1 | 0.95685 | 0.60885 | 0.7253 | 0.9924 | 0.50565 | 0.748 |
| U1 | 0.9642 | 0.78035 | 0.7368 | 0.85725 | 0.8601 | 0.78205 |
| U2 | 0.8759 | 0.74055 | 0.70125 | 0.83575 | 0.53745 | 0.7721 |
| S1 | 3.2293 | 2.5016 | 1.92195 | 9.2856 | 2.22845 | 1.85555 |
| S2 | 2.963 | 2.051 | 2.0203 | 9.39085 | 2.2397 | 2.62835 |
| S3 | 3.1109 | 2.7788 | 2.0137 | 9.38075 | 2.26215 | 2.74975 |
| S4 | 9.6427 | 9.6553 | 7.2891 | 10.2789 | 5.9647 | 4.9492 |
在MS SQLSever中:索引不会明显影响数据库进行插入和删除操作。在大多数情况下,聚集索引的效率都比非聚集索引的高。即聚集索引在小规模数量级的数据表中是最佳选择。
同样的情况出现在MySQL数据库。
索引对于查询的耗时的降低是非常明显的。
计划在百万级的数据表中再重新设计做一次实验。
基于Python的数据分析:数据库索引效率探究的更多相关文章
- 基于Python的数据分析(2):字符串编码
在上一篇文章<基于Python的数据分析(1):配置安装环境>中的第四个步骤中我们在python的启动步骤中强制要求加载sitecustomize.py文件并设置其默认编码为"u ...
- 基于Python的数据分析(1):配置安装环境
数据分析是一个历史久远的东西,但是直到近代微型计算机的普及,数据分析的价值才得到大家的重视.到了今天,数据分析已经成为企业生产运维的一个核心组成部分. 据我自己做数据分析的经验来看,目前数据分析按照使 ...
- 基于Python的数据分析(3):文件和时间
在接下来的章节中,我会重点介绍一下我自己写的基于之前做python数据分析的打包接口文件common_lib,可以认为是专用于python的第三方支持库.common_lib目前包括文件操作.时间操作 ...
- 利用Python进行数据分析
最近在阅读<利用Python进行数据分析>,本篇博文作为读书笔记 ,记录一下阅读书签和实践心得. 准备工作 python环境配置好了,可以参见我之前的博文<基于Python的数据分析 ...
- 基于Python的SQL Server数据库对象同步轻量级实现
缘由 日常工作中经常遇到类似的问题:把某个服务器上的某些指定的表同步到另外一台服务器.类似需求用SSIS或者其他ETL工作很容易实现,比如用SSIS的话就可以,但会存在相当一部分反复的手工操作.建源的 ...
- 向大家介绍我的新书:《基于股票大数据分析的Python入门实战》
我在公司里做了一段时间Python数据分析和机器学习的工作后,就尝试着写一本Python数据分析方面的书.正好去年有段时间股票题材比较火,就在清华出版社夏老师指导下构思了这本书.在这段特殊时期内,夏老 ...
- 数据分析:基于Python的自定义文件格式转换系统
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 基于python的Elasticsearch索引的建立和数据的上传
这是我的第一篇博客,还请大家多多指点 Thanks ♪(・ω・)ノ 今天我想讲一讲关于Elasticsearch的索引建立,当然提前是你已经安装部署好Elasticsearch. ok ...
- 利用Python进行数据分析(5) NumPy基础: ndarray索引和切片
概念理解 索引即通过一个无符号整数值获取数组里的值. 切片即对数组里某个片段的描述. 一维数组 一维数组的索引 一维数组的索引和Python列表的功能类似: 一维数组的切片 一维数组的切片语法格式为a ...
随机推荐
- STL:set/multiset用法详解
集合 使用set或multiset之前,必须加入头文件<set> Set.multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素. sets和mul ...
- 【一天一道LeetCode】#33. Search in Rotated Sorted Array
一天一道LeetCode 本系列文章已全部上传至我的github,地址: https://github.com/Zeecoders/LeetCode 欢迎转载,转载请注明出处 (一)题目 Suppos ...
- spring mvc接收List集合、JUI传JSP List
JUI页面是这样的 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <div class=&quo ...
- [WinForm]最小化到系统托盘,右键退出
1.拉出一个notifyIcon1到用户界面,也可以NEW一个 2.拉出一个ContextMenuStrip控件,命名为mymenu,集合中增加退出 3.notifyIcon1的属性ContextMe ...
- python3.4 + Django1.7.7 表单的一些问题
上面是没有调用cleaned_data的提交结果,可见模版直接把form里面的整个标签都接收过来了 下面是调用cleaned_data 的结果 django 的表单,提交上来之后是这样的: #codi ...
- Google地球查看香港地形
12月1号要去香港.为此需要先了解一下香港的情况.以前只知道用Google地球看别人照的照片(或者是全景照),这次无意间发现了它一个很强大的功能:立体的呈现一个地区的地形.对于像香港这样的多山地区来说 ...
- mpi中的广播
MPI可以实现一对多的集合通信,最常用的是广播:某个进程将数据广播到所有其他进程,最终的结果就是每个进程都有一份广播的数据.MPICH中的广播函数是MPI_Bcast(void* buffer,int ...
- Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验
Android群英传笔记--第十二章:Android5.X 新特性详解,Material Design UI的新体验 第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看 Android高 ...
- 【面试笔试算法】牛客网一站通Offer编程题2016.4.19
牛客网一站通offer (一)字符串变形 1. 题目: 对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形.首先这个字符串中包含着一些空格,就像"Hello Wor ...
- 纯命令提交代码到git仓库(教你怎么装逼)
如果不喜欢用命令的请点链接:http://blog.csdn.net/xiangzhihong8/article/details/50715427 我这里用纯命令,主要是因为这两天不知道什么原因,ba ...