Index--复合索引的思考1
在创建复合索引时,除了考虑索引键的选取外,还需考虑索引键的先后顺序。下面借助一些场景来讲解。
场景1
表dbo.UserLoginStats记录每个用户每天的登录统计,目前表中存放10亿数据,每天新增数据500W(每天每个用户很少几条条记录),目前系统有用户8000W,有查询:
SELECT * FROM dbo.UserLoginStats
WHERE UserID=@userID
AND LoginDay=@loginDay
对于此查询,可以创建索引:
CREATE INDEX IX_UserID_LoginDay
ON dbo.UserLoginStats(UserID,LoginDay)
或
CREATE INDEX IX_LoginDay_UserID
ON dbo.UserLoginStats(LoginDay,UserID)
以上两种索引都可以帮助查询快速返回结果,并且消耗的IO相同,消耗的CPU时间也大致相同,因此对于该查询来说,两个索引没有区别,但我们该使用哪一个查询呢?
假设索引行每行占用20个字节,每个索引页存放400条记录,则10亿数据需要约2500W个索引页。
对于索引IX_LoginDay_UserID(LoginDay,UserID):
每天新增的500W新纪录存放在一起,需要约1.3万个索引页来存放,只需要100MB的内存来存放,在数据读取和写入时,更多的是顺序IO。
对于索引IX_UserID_LoginDay(UserID,LoginDay):
每天新增的500W数据需要分散存放到索引的各个页面中,可能影响到数百万的索引页,需要1GB到5GB的内存,在数据读取和写入时,更多的是随机IO。
因此,在不考虑其他因素影响的条件下,针对该场景,索引IX_LoginDay_UserID(LoginDay,UserID)时最佳的。
误区:在创建复合索引时,很多人会将选择性较高的列放在前面,
解释:可选择性是我们在挑选索引键时考虑的一个因素,通常会选择性较高的备选键来创建索引,但不意味该键就应该放在索引前面。
PS: 在笔者维护的系统中,曾出现过类似问题,在checkpoint时需要写入上万个不连续的数据页,导致很高的磁盘队列,同时还导致在日志备份还原时消耗大量的时间。
PS2:针对该问题,数据分区和历史数据定期数据归档也是很好的解决办法。
惯例上图引狼

图片来源:http://www.douban.com/photos/photo/353424799/
Index--复合索引的思考1的更多相关文章
- SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)
本文出处:http://www.cnblogs.com/wy123/p/6008477.html 关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里. ...
- SQL Server创建复合索引时,复合索引列顺序对查询的性能影响
说说复合索引 写索引的博客太多了,一直不想动手写,有一下两个原因:一是觉得有炒剩饭的嫌疑,有兄弟曾说:索引吗,只要在查询条件上建索引就行了,真的可以这么暴力吗?二来觉得,索引是个非常大的话题,很难概括 ...
- Sql Server之旅——第八站 复合索引和include索引到底有多大区别?
周末终于搬进出租房了,装了宽带....才发现没网的日子...那是一个怎样的与世隔绝呀...再也受不了那样的日子了....好了,既然网 安上去了,还得继续我的这个系列. 索引和锁,这两个主题对我们开发工 ...
- MySQL 优化之 index merge(索引合并)
深入理解 index merge 是使用索引进行优化的重要基础之一.理解了 index merge 技术,我们才知道应该如何在表上建立索引. 1. 为什么会有index merge 我们的 where ...
- 使用复合索引代替单键索引,来避免单键有null值的情况
查看原表: SQL> select count(*) from t1; COUNT(*) ---------- 3229088 SQL> select count(*) from t1 w ...
- SQL SERVER大话存储结构(4)_复合索引与包含索引
索引这块从存储结构来分,有2大类,聚集索引和非聚集索引,而非聚集索引在堆表或者在聚集索引表都会对其 键值有所影响,这块可以详细查看本系列第二篇文章:SQL SERVER大话存储结构 ...
- Index Scans 索引扫描
官方文档链接地址 http://docs.oracle.com/cd/E11882_01/server.112/e40540/indexiot.htm#CNCPT1170 Index Scans 在索 ...
- MongoDB复合索引详解
摘要: 对于MongoDB的多键查询,创建复合索引可以有效提高性能. 什么是复合索引? 复合索引,即Compound Index,指的是将多个键组合到一起创建索引,这样可以加速匹配多个键的查询.不妨通 ...
- ORACLE Index Lookup索引访问路径总结
在ORACLE中,索引访问/查找(Index Lookup)路径有五种方式,分别为INDEX UNIQUE SCAN.INDEX RANGE SCAN.INDEX FULL SCAN.INDEX FA ...
- mySql的普通索引和复合索引
有关普通索引和组合索引问题: 索引分单列索引和组合索引:单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引:组合索引,即一个索包含多个列. MySQL索引类型包括: ...
随机推荐
- 【ZZ】C++静态库与动态库 | 菜鸟教程
C++静态库与动态库 http://www.runoob.com/w3cnote/cpp-static-library-and-dynamic-library.html
- [转]FluentData
本文来自:http://fluentdata.codeplex.com/wikipage?title=Fluency&referringTitle=Home Documentation Fl ...
- 1021 docker prometheus监控体系
jmeter plugin监控的信息很少,只有cpu.内存.网络IO,但这些是不够的.例如对于分析mysql数据库的慢查询.最大连接数等更加细密度的信息. 服务端稳定测试的三个前提: 1.应用级别的自 ...
- 使用word设置标题级别, 自动生成和大纲对应的多级列表, 自动生成索引目录
作为程序员,只会开发是不够的, 在日常工作中还需要掌握一些办公软件的的操作方法,word excel ppt精通不敢, 暂且入个门吧, 在前后台开发配合过程中,能写的一手好文档将会达到事半功倍的效果, ...
- [ML] CostFunction [Octave code]
function J = computeCostMulti(X, y, theta) m = length(y); % number of training examples J = 0; for i ...
- 496. Next Greater Element I + 503. Next Greater Element II + 556. Next Greater Element III
▶ 给定一个数组与它的一个子列,对于数组中的一个元素,定义它右边第一个比他大的元素称为他的后继,求所给子列的后继构成的数组 ▶ 第 496 题,规定数组最后一个元素即数组最大元素的后继均为 -1 ● ...
- 关于rand 与 randn
rand:0-1均匀分布.均值m=(a+b)/2; 方差=(b-a).^2/12; randn:0均值,方差1. 只有当rand和randn生成较大的数据时,均值和方差才会成立.比如N&g ...
- leetcode475
public class Solution { public int FindRadius(int[] houses, int[] heaters) { houses = houses.Distinc ...
- U3D 如何计算一个UI四个角的绝对坐标
//方式一,使用API获取 var rtrans = gameObject.GetComponent<RectTransform>(); Vector3[] worldcorners ...
- StretchBlt
StretchBlt 函数从源矩形中复制一个位图到目标矩形,必要时按目前目标设备设置的模式进行图像的拉伸或压缩以满足目标矩形的尺寸. 原型: BOOL StretchBlt( HDC hdcDest ...