第五章 创建高性能的索引
5.1索引基础
5.1.1 索引的类型
5.1.1.1 B-Tree索引
5.1.1.2 哈希索引
5.1.1.3 空间数据索引(R-Tree)
5.1.1.4 全文索引
5.2 索引的优点
5.3 高性能的索引策略
5.3.1 独立的列
5.3.2 前缀索引和索引选择性
5.3.3 多列索引
5.3.4 选择合适的索引列顺序(B-Tree场景)
5.3.5 聚簇索引(主要关注InnoDB)
5.3.6 覆盖索引
5.3.8 压缩(前缀压缩)索引(MyISAM)
5.3.9 冗余和重复索引
5.3.10 未使用的索引
5.3.11 索引和锁
5.4 索引案例学习
5.4.1 支持多种过滤条件
5.4.2 避免多个范围条件
5.4.3 优化排序
5.5 维护和索引表
5.5.1 找到并修复顺坏的表
5.5.2 更新索引统计信息
5.5.3 减少索引和数据的碎片
5.6总结
索引是存储引擎用于快速找到记录的一种数据结构。
对良好的性能非常关键。尤其是表中的数据较大时,索引对性能的影响愈发重要。
对查询性能优化最有效的手段。轻易将查询性能提高几个数量级。
5.1索引基础
索引,又叫key(键)
存储引擎使用索引,先在索引中找到对应的值,然后根据匹配的索引记录找到对应的数据行。
可以包含一个或多个列的值。如果包含多个列,那么列的顺序也很重要,因为MySQL只能高效地使用索引的最左前缀列。
最左前缀:就是KEY(id, name, sex)中,id在id、name、sex里面是写在左边的,id就叫最左前缀
5.1.1 索引的类型
索引是在存储引擎层 而不是服务器层实现的,所以没有统一的索引标准:不同存储引擎的索引的工作方式不一样,也不是所有的存储引擎都支持所有类型的索引。即使多个存储引擎支持同一种类型的索引,其底层的实现也可能不同。
5.1.1.1 B-Tree索引
实际上很多存储引擎使用的是B+Tree,即每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。
innoDB使用B+Tree
B-Tree意味着所有的数据都是按顺序存储 ,适合查找某一范围内的数据,对数据排序。
可加快访问数据的速度,存储引擎不再需要扫描全表 ,而是从根节点开始进去搜索。
既然索引按顺序存储,也就意味着它对数据排序 了,索引对数据排序的依据是按照定义索引的顺序来排序,例如KEY(id, name, sex),先对id排序,再是name,最后是sex。
B-Tree索引适用于全键值 、键值范围 或键前缀查找 ,其中键前缀查找只适用于根据最左前缀的查找。
全值匹配。全值匹配指的是和索引中的所有列进行匹配,例如,前述示例中的索引可用于查找姓名为Cuba Allen、出生于1960-01-01的人。
匹配最左前缀。示例索引可用于查找所有姓为Allen的人,即只使用索引的第一列。
匹配列前缀。也可以只匹配某一列的值的开头部分,例如,示例索引可用于查找所有以J开头的姓的人,这里也只使用了索引的第一列。
匹配范围值。例如,示例索引可用于查找姓在Allen和Barrymore之间的人,这里也只使用了索引的第一列。
精确匹配某一列并范围匹配另外一列。示例索引也可用于查找所有姓为Allen,并且名字是字母K开头的人,即第一列last_name全匹配,第二列first_name范围匹配。
只访问索引的查询。B-Tree通常可以支持“只访问索引的查询”,即查询只需要访问索引,而无须访问数据行。
因为索引树中的结点是有序的,所以除了按值查找之外,索引还可以用于查询中的ORDER BY操作。一般来说,如果B-Tree可以按照某种方式查找到值,那么也可以按照这种方式用于排序。所以,如果ORDER BY子句满足前面列出的几种查询类型,则这个索引也可以满足对应的排序需求。
限制
如果不是按照索引的最左列开始查找,则无法使用索引。例如,示例索引中无法用于查找名字为Bill的人,也无法查找某个特定生日的人,因为这两列都不是最左数据列。类似的,也无法查找姓氏以某个字母结尾的人。
不能跳过索引中的列。例如,示例索引无法用于查找姓为Smith并且在某个特定日期出生的人。如果不指定first_name,则mysql只能使用索引的第一列。
如果索引中有某个列的范围查询,则其右边所有列都无法使用索引优化查找。例如,示例索引中有如下查询语句WHERE last_name = ‘Smith’ AND first_name LIKE ‘J%’ AND dob = ‘1976-12-23’,此查询只能使用索引的前两列,因为这里LIKE是一个范围条件。如果范围查询列值的数量有限,那么可以通过使用多个等于条件来代替范围条件。
上述限制都和索引列的顺序有关,在优化性能时,可能需要使用相同的列但顺序不同的索引来满足不同类型的查询需求。也有些限制并不是B-Tree本身导致的,而是mysql优化器和存储引擎使用索引的方式导致的。
想要了解B-Tree和B+Tree可以参考博客:https://blog.csdn.net/u010727189/article/details/79399384
5.1.1.2 哈希索引
哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的查询才有效 。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。
在mysql中,只有Memory引擎显式支持哈希索引。这也是Memory引擎表的默认索引类型,Memory引擎同时也支持B-Tree索引。Memory引擎支持非唯一哈希索引,如果多个列的哈希值相同,索引会以链表的方式存放多个记录指针到同一个哈希条目中。
索引自身只需存储对应的哈希值,所以索引的结构十分紧凑,也让哈希索引查找的速度非常快。
限制 :
只包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行。但由于在内存中,对性能的影响并不明显。
并不是按照索引值顺序存储的,所以无法用于排序。
不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值。
只支持等值比较查询,包括=、IN()、<=>。也不支持任何范围查询。
访问哈希索引的数据非常快,除非有很多哈希冲突(不同索引列值却有相同的hash值)。当出现哈希冲突时,存储引擎必须遍历所有的行指针,逐行比较,直到找到对应的行。
如果哈希冲突很多的话,一些索引维护操作的代价也非常高。例如删除一行时,需遍历对应哈希值的每一行。
应用场景: 数据仓库应用中有一种经典的“星型”schema,需要管理很多查找表
InnoDB的自适应哈希索引(adaptive hash index): 当InnoDB注意到某些值被使用的非常频繁时,会在内存中基于B-Tree索引之上在创建一个hash索引,从而拥有hash索引的优点,如快速的hash查找。这是一个完全自动的,内部的行为,用户无法控制或者配置,但可以关闭。
创建自定义哈希索引:
如果存储引擎不支持hash索引,可以模仿像InnoDB一样创建hash索引。
思路:在B-Tree基础上创建一个伪哈希索引,即将要索引的列删除索引,对其创建一个被索引哈希列,里面存放原索引列每一行数据的哈希值。
缺陷:需要维护哈希值,可以手动维护,也可以使用触发器实现。
使用时不要使用SHA1()和MD5()作为哈希函数,因为这两个函数计算出来的哈希值非常长,浪费大量空间而且比较时也会更慢。可以使用CRS32()。
如果数据表非常大,CRS32()会出现大量的数据冲突,可以自行实现一个简单的64位哈希函数,这个函数要返回整数,而不是字符串。也可以使用MD5()函数返回值的一部分来作为哈希函数。
SELECT CONV(RIGHT(MD5("str"), 16), 16, 10) AS HASH64
使用哈希索引进行查询时,必须在WHERE子句包含对应列值,因为可能会有哈希冲突从而选出多个不同的数据。
5.1.1.3 空间数据索引(R-Tree)
与B-Tree不同,这类索引无需前缀查询,会从所有维度来索引数据。
查询时可以使用任意维度来组合查询。
必须使用MySQL的GIS相关函数如MBRCONTAINS()等来维护数据。(MySQL的GIS支持不完善,开源关系数据库中较好的解决方案是PostgreSQL的PostGIS)。
MyISAM表支持空间索引,可以用作地理数据存储。
5.1.1.4 全文索引
查找的是文中关键词,而不是直接比较索引中的值。
与其他索引完全不一样,需注意如停用词、词干和复数、布尔搜索等细节。
更类似于搜索引擎做的事,而不是简单的WHERE条件匹配。
在相同列上同时创建全文索引和基于值的B-Tree索引不会有冲突,全文索引适用于MATCH AGAINST操作
为什么索引结构默认使用B-Tree,而不是hash,二叉树,红黑树?
hash:虽然可以快速定位,但是没有顺序,IO复杂度高。
二叉树:树的高度不均匀,不能自平衡,查找效率跟数据有关(树的高度),并且IO代价高。
红黑树:树的高度随着数据量增加而增加,IO代价高。
5.2 索引的优点
优点:
大大减少服务器需要扫描的数据量
帮助服务器避免排序和临时表(B-Tree会将相关的列值存储在一起,便于ORDER BY 和GROUP BY进行排序)
可以将随机I/O变为顺序I/O
索引适合某个查询的“三星系统”:
将相关记录放到一起则获得一星
索引中的数据顺序和查找中的排列顺序一致获得二星。
索引中的列包含了查询中需要的全部列获得三星。
索引并不是最好的解决方案:
非常小的表,大部分情况下全表扫描更高效。
中到大型的表,索引非常有效。
特大型的表,建立和使用索引的代价随之增长,需要区分出查询需要的一组数据,如分区技术。
表的数量特别多,可以建立一个元数据信息表,用来查询需要用到的某些特性。例如执行那些需要聚合多个应用分布在多个表的数据的查询,则需要记录“哪个用户的信息存储在哪个表中”的元数据,这样在查询时就可以直接忽略掉那些不包含指定用户信息的表。对大型系统是一个常用的技巧.
对于TB级别的数据,定位单条记录的意义不大,所以经常使用块级元数据技术来代替索引.
5.3 高性能的索引策略
5.3.1 独立的列
索引列不能是表达式的一部分,也不能是函数的参数。因为MySQL无法自动解析
WHERE column + 1 = 5 AND TO_DAYS(CURRENT_DATE) - TO_DAYS(date_col) <= 10
无法使用索引
因此在写SQL语句时应该养成简化WHERE条件的习惯,始终将索引列单独放在比较符的一侧。
5.3.2 前缀索引和索引选择性
当索引是很长的字符列时,会让索引变得大且慢。一个策略是模拟的哈希索引,另一个策略是前缀索引。
索引选择性:
指不重复的索引值(也称基数,cardinality)和数据表的记录总数(#T)的比值
选择性越高则查询效率越高,唯一索引的选择性是1,性能是最好的。
前缀索引:
索引开始的部分字符串,即可节约索引空间,也可提高索引效率,但会降低索引的选择性。
一般情况下某个列前缀的选择性也是足够高的,足以满足查询性能。
针对BLOB,TEXT或很长的VARCHAR类型的列,必须使用前缀索引,因为MySQL不允许索引这些列的完整长度。
选择前缀长度的诀窍:保持较高的选择性(接近于索引完整列),同时又不能太长。换句话说,前缀的基数应接近于完整列的基数。
方法: 先计算出完整列的选择性:SELECT COUNT(DISTINCT col)/COUNT(*) FROM mytable
, 再与平均选择性和最差选择性比较。
SELECT COUNT(DISTINCT LEFT(col, 3))/COUNT(*) AS sel3,
COUNT(DISTINCT LEFT(col, 4))/COUNT(*) AS sel4,
...
FROM mytable;
最差选择性:针对平均选择性选出的多个前缀长度,考虑其数据分布很不均匀下的选择性。
缺点:
MySQL无法使用前缀索引做ORDER BY和GROUP BY
无法做覆盖扫描
应用场景: 针对很长的十六进制唯一ID,如保存网站的会话(SESSION),可采用长度为8的前缀索引,而且对上层应用完全透明。
有时使用后缀索引也有用途,如找到某个域名的所有电子邮件地址。但MySQL原生不支持反向索引,可以通过触发器把字符串反转后存储,并基于此建立前缀索引。
5.3.3 多列索引
在多个列上建立独立的单列索引大部分情况下并不能提高MySQL的查性能。
MySQL5.0及以后版本引入“索引合并(index merge)"的策略,一定程度上可以使用表上的多个单列索引来定位指定的行。对示例查询同时使用两个单列索引进行扫描,并将结果进行合并,可以通过EXPLAIN的Extra看到过程。这算法有三个变种:
OR条件的联合(union)
AND条件的相交(intersection)
组合前两种情况的联合及相交
更早版本的MySQL只能使用其中的某一个单列索引,而这种情况下没有哪一个独立的单列索引是非常有效的。对示例查询使用全表扫描,除非改成UNION的方式。
-- 两个单列索引的查询
mysql> SELECT film_id, actor_id FROM sakila.film_actor
-> WHERE actor_id = 1 OR film_id = 1;
索引合并策略有时候是一种优化的结果,但实际上更多时候说明了表上的索引建得很糟糕:
当出现服务器对多个索引做相交操作时(通常有多个AND条件),通常意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引
当服务器对多个索引做联合操作时(通常有多个OR条件),通常需要耗费大量的CPU和内存在算法的缓存、排序和合并操作上。特别是当其中有些索引的选择性不高,需要合并扫描返回的大量数据的时候。
优化器不会把这些计算到“查询成本(cost)”中,而优化器只关心随机页面读取。这会使得查询的成本被低估,导致执行该计划还不如直接走全表扫描。这样做不但会消耗更多的CPU和内存资源,还可能会影响查询的并发性,但如果是单独运行这样的查询往往会忽略对并发性的影响。通常来说,将查询改为UNION的方式往往更好 。
如果在EXPLAIN中看到有索引合并,应检查下查询和表的结构以达到最优。也可以通过参数optimizer_switch来关闭索引合并功能,或使用INGORE INDEX提示让优化器忽略掉某些索引。
5.3.4 选择合适的索引列顺序(B-Tree场景)
正确的顺序依赖于使用该索引的查询,并且同时需要考虑如何更好地满足排序和分组的需要。
选择索引列顺序的经验法则:
当不需要考虑排序和分组时,将选择性最高的列放到索引最前列
性能不只是依赖于所有索引列的选择性(整体基数),也和查询条件的具体值有关,也就是和值的分布有关。
如果某些索引值的选择性非常小,即匹配的范围非常大,说明该索引基本没什么用。该特殊情况可能会摧毁整个应用的性能。
5.3.5 聚簇索引(主要关注InnoDB)
聚簇索引不是一种单独的索引类型,而是一种数据存储的方式 。具体的细节依赖于其实现方式,但InnoDB的聚簇索引实际上在同一个结构中保存了B-Tree索引和数据行 。
当表有聚簇索引时,它的数据行实际上存放在索引中的叶子页(leaf page)中,但节点也只包含了索引列 。术语的“聚簇”表示数据行和相邻的键值紧凑地存放在一起(Oracle中为索引组织表)。如图,被索引的列是主键列
一个表只能有一个聚簇索引,因为无法同时将数据行存放在两个不同的地方
MySQL内建的存储引擎不支持选择索引作为聚簇索引,InnoDB将通过主键聚集数据,其默认使用聚簇索引: 如果没有定义主键,InnoDB会选择一个唯一的非空索引。 如果没有唯一的非空索引,InnoDB会隐式定义一个主键。
InnoDB只聚集在同一个页面的记录,包含相邻键值的页面可能会相距甚远。
优缺点 :
优点(设计表和查询时充分利用可极大地提升性能):
可以把相关数据保存在一起。如实现电子邮箱时,根据用户ID来聚集数据,这样只需从磁盘读取少数的数据页就能获取某个用户的全部邮件。如果没有使用聚簇索引,则每封电子邮件都可能导致一次磁盘IO。
数据访问更快。因为索引和数据都保存在同一个B-Tree中。
使用覆盖索引扫描的查询可以直接使用页节点中的主键值。
缺点:
最大限度地提高了I/O密集型应用的性能,但如果数据全部存放在内存中,则访问的顺序就没那么重要了,聚簇索引也就没什么优势。
插入速度严重依赖于插入顺序。按照主键的顺序插入是加载数据到InnoDB表中速度最快的方式。如果不是按照主键顺序加载数据,加载完成后最好使用OPTIMIZE TABLE命令重新组织一下表。
更新聚簇索引列的代价很高,因为会强制InnoDB将每个被更新的行移动到新的位置。
基于聚簇索引的表在插入新行,或者主键被更新导致需要移动行的时候,可能面临“页分裂(page split)”的问题。当行的主键值要求必须将这一行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳该行,这会导致表占用更多的磁盘空间。
可能导致全表扫描变慢,尤其是行比较稀疏,或者由于页分裂导致数据存储不连续的时候。
二级索引(非聚簇索引)可能比想象的要更大,因为在二级索引的叶子节点包含了引用行的主键列。
二级索引访问需要两次索引查找,而不是一次。因为二级索引叶子节点保存的不是指向行的物理位置的指针,而是行的主键值。(InnoDB的自适应哈希索引能够减少这样的重复工作)
InnoDB:
由于采用了聚簇索引,其保存了整个表
聚簇索引每个叶子节点都包含了主键值、事务ID、用于事务和MVVC的回滚指针以及所有的剩余列。
二级索引的叶子节点存储的不是"行指针",而是主键值,并以此作为指向行的“指针”。即叶子节点包含被索引的列和主键列。这样的策略会让二级索引占用更多的空间,但减少了当出现行移动或者数据页分裂时二级索引的维护工作,因为无须更新二级索引中的指针。
MyISAM
采用了独立的行存储,按照数据插入的顺序存储在磁盘上
主键索引和其他索引在结构上一样,主键索引是一个名为PRIMARY的唯一非空索引。
在InnoDB表中按主键顺序插入行:
如果没有数据需要聚集,建议定义一个代理键作为主键,并且主键的数据应该和应用无关。最简单是使用AUTO_INCREMENT自增列,这样可以保证数据行是按顺序写入的,对于根据主键做关联操作的性能更好。
最好避免随机的(不连续且值的分布范围非常大)聚簇索引,特别是对于I/O密集型的应用,比如使用UUID作为聚簇索引可能会带来糟糕的性能,它使得聚簇索引的插入完全随机,使得插入行的时间更长,而且索引占用的空间更大。因为主键的字段更长,还由于页分裂和碎片导致。
根据顺序id插入数据 : 每条记录都存储在上一条记录的后面,当达到页的最大填充因子时(InnoDB默认为页大小的15/16,留出部分空间用于以后修改),下一条记录会插入新的页中。一旦数据按照这种顺序的方式加载,主键页就会被近似于被顺序的记录填满(二级索引页可能是不一样的) 造成更坏结果的场景: 1.对于高并发工作负载,可能会造成明显的争用。因为所有的插入都发生在这里,可能导致间隙锁竞争。 2.AUTO_INCREMENT锁机制也可能会被争用,需考虑重新设计表或者应用,或者更改innodb_autoinc_lock_mode配置。
使用随机id插入数据: 新行的主键值不一定比之前插入的大,因此需要为新行找到合适的位置——通常是已有数据的中间位置——并分配空间。这会增加很多额外的工作,并导致数据分布不够优化。
使用随机id插入数据缺点:
写入的目标页可能已经刷新到磁盘并从缓存中移除,或是还没有被加载到缓存中,InnoDB在插入之前需先从磁盘读取目标页到内存中,这将导致大量的随机IO。
因为写入是乱序的,需要频繁地做页分裂操作,以便为新行分配空间。因为页分裂会导致移动大量数据,一次插入最少需要修改三个页而不是一个页。
由于频繁的页分裂,页会变得稀疏并被不规则地填充,所以最终数据会有碎片。
5.3.6 覆盖索引
设计优秀的索引应该考虑到整个查询,而不单单是WHERE条件部分
覆盖索引:一个索引包含(覆盖)所有需要查询的字段的值 ,查询只需要扫描索引而无须回表读取数据行
好处:
索引条目通常小于数据行大小,如果只需要读取索引会极大地减少数据访问量。这对缓存的负载 非常重要,因为这种情况下响应时间大部分花在数据拷贝上 。覆盖索引对I/O密集型的应用也有帮助,因为索引比数据更小,更容易全部放入内存中(尤其是MyISAM能压缩索引)
索引是按照列值顺序存储的(至少在单个页内是如此 ),所以对于I/O密集型的范围查询会比随机从磁盘读取每一行数据的IO要少得多。
一些存储引擎如MyISAM在内存中只缓存索引,数据则依赖于操作系统来缓存,因此访问数据需要一次系统调用。这可能会导致严重的性能问题,尤其是那些系统调用占了数据访问中的最大开销。
覆盖索引对使用了聚簇索引的InnoDB的表非常有用。InnoDB的二级索引在叶子节点保存了行的主键值 ,所以如果二级节点能够覆盖查询,则可以避免对主键索引的二次查询 。
覆盖索引必须要存储索引列的值,而哈希索引、空间索引和全文索引都不存储,MySQL只能使用B-Tree索引做覆盖索引 。
无法使用覆盖索引的原因:
没有任何索引能够覆盖这个查询。
不能在索引执行LIKE操作。
可以使用延迟关联和覆盖索引,因为延迟了对列的访问。先在查询第一阶段使用覆盖索引,再在外层查询所要获取的列值。
InnoDB的二级索引的叶子节点包含了主键的值,这意味着二级索引可以有效地利用这些主键列来覆盖查询。
-- last_name字段有二级索引,虽然该索引的列不包括逐渐actor_id,但也能用于对actor_id做覆盖查询
mysql>EXPLAIN SELECT actor_id, last_name
-> FROM sakila.actor WHERE last_name = "HOPPER"\G
使用InnoDB的表通过主键查询所有列,并不是覆盖查询,虽然聚簇索引的叶子节点包含了所有列的数据,但它只是一种数据存储方式,并不算索引。
5.3.8 压缩(前缀压缩)索引(MyISAM)
MyISAM使用前缀压缩来减少索引大小,从而让更多索引可以放入内存中,在某些情况下能极大地提高性能。
默认只压缩字符串,通过设置也能压缩整数。
压缩每个索引块的方法:先完全保存索引块的第一个值,然后将其他值和第一个值比较得到相同的前缀字节数和剩余的不同后缀部分,再把这部分存储起来。MyISAM对指针也采用类似的压缩方式。
压缩块使用更少的空间,代价是某些操作可能更慢。因为每个值都依赖前面的值,无法使用二分查找只能从头开始扫描,而对倒序的扫描性能更差。
对CPU密集型应用,因为扫描经常要随机查找,不推荐使用该索引。
在CREATE TABLE语句中制定PACK_KEYS参数来控制索引压缩的方式。
5.3.9 冗余和重复索引
冗余索引 :在相同列上创建多个索引。MySQL需要单独维护重复的索引,并且优化器在查询时也需要逐个考虑,可能会影响性能。
(A)是(A,B)的冗余索引,(B,A)和(B)则不是(A,B)的冗余索引,只针对B-Tree索引来说.
(A,ID)也是冗余索引,因为对InnoDB主键列已经包含在二级索引中。
其他类型的如哈希索引也不会是B-Tree的冗余索引。
增加新索引会导致INSERT,UPDATE等操作的速度变得更慢,特别是新增索引达到了内存瓶颈的时候。
重复索引 :在相同列上按照相同顺序创建的相同类型的索引。应该避免这种操作,常见错误做法是对一个主键添加唯一限制和查询索引,这属于三个重复的索引。(如果索引的类型不同,并不算重复索引)
大多数情况下都不需要冗余索引,应该尽量扩展已有的索引而不是创建新的索引。除非扩展已有的索引会导致其变得太大,从而影响其他使用该索引查询的性能。
假如在整数列上有一个查询,现在需要额外增加很长的VARCHAR列来扩展该索引,可能会导致性能急剧下降。特别是有查询把这个索引当作覆盖查询,或者是MyISAM表并且有很多范围查询。
-- Q1查询:
SELECT count(*) FROM userinfo WHERE state_id=5;
-- Q2查询:
SELECT state_id, city, address FROM userinfo WHERE state_id=5;
-- Q2的查询速度会比Q1慢,最简单的办法是扩展索引变成覆盖查询:
ALTER TABLE userinfo DROP key state_id, ADD KEY state_id_2 (state_id, city, address);
-- 索引扩展后,Q2运行更快,但Q1变慢了。如果想要两个查询都变得更快,就需要两个索引,尽管这是冗余的。
解决冗余和重复索引的办法只需要删除它们 。找出这些索引的办法:
写一些复杂的访问INFORMATION_SCHEMA表的查询(服务器如果有大量的数据或表,可能会导致性能问题)
第三方工具。
由于二级索引包含了主键值,因此(A)相当于(A,ID) ,对WHERE A=5 ORDER BY ID
这样的查询很有用 。但如果(A)扩展为(A,B)相当于(A,B,ID),前面的查询就无法使用该索引排序,而只能用文件排序。
5.3.10 未使用的索引
找出未使用的索引,并且删除!不过有些索引的功能相当于唯一约束,虽然一直没被查询使用,但是是用于避免产生重复数据的。
5.3.11 索引和锁
索引可以锁定更少的行。如果查询从不访问那些不需要的行,那么就会锁定更少的行:
虽然InnoDB的行锁效率很高,内存使用也很少,但是锁定行的时候仍然会带来额外的开销。
锁定超过需要的行会增加锁争用并减少并发性。
InnoDB只有在访问行的时候才会对其加锁,而索引能够减少InnoDB访问的行数,从而减少锁的数量 。但只有当InnoDB在存储引擎层能够过滤掉所有不需要的行时才有效。
如果索引无法过滤掉无效的行,那么在InnoDB检索到数据并返回给服务器层后,MySQL服务器才能应用WHERE子句。而这时候InnoDB已经锁住了这些行(包含有没被索引的行数据,这些是要在服务器层被过滤掉的,因为索引只在存储引擎层工作 ),到适当的时候才释放。
MySQL5.0及新版本,InnoDB可以在服务器端过滤掉行就释放锁 ;但在早期版本,只有在事务提交后才能释放锁。
如果不使用索引查找和锁定行的话,MySQL可能会做全表扫描并锁住所有的行,而不管是否需要。
InnoDB在二级索引上使用共享(读)锁,但访问主键索引需要排他(写)锁,这消除了使用覆盖索引的可能性 ,并且使得SELECT FOR UPDATE
比LOCK IN SHARE MODE
或非锁定查询要慢得多。
5.4 索引案例学习
设计一个在线约会网站,用户信息表包括国家、地区、城市、性别、眼睛颜色等等。网站必须支持上面这些特征的各种组合来搜索用户,还必须允许根据用户的最后在线时间、其他会员对用户的评分等对用户进行排序并对结果进行限制。
使用索引排序,还是先检索数据再排序?使用索引排序会严格限制索引和查询的设计。
5.4.1 支持多种过滤条件
先看哪些列拥有不同的取值,哪些列在WHERE子句中出现得最频繁。
country和sex选择性通常比较低,考虑到使用频率,建议将(sex, country)作为查询前缀
即使查询没有使用sex列,也可在查询条件中新增AND SEX IN(‘m’, ‘f’)来绕过,因为只有加上了sex这个条件,MySQL才能够匹配索引的最左前缀。但如果列有太多的值而导致IN()列表太长,或则IN()的数量太多导致有太多的组合,则不建议使用该技巧。
基本原则之一:考虑表上的所有选项。当设计索引时,不要只为现有的查询考虑需要哪些索引,还需要考虑对查询进行优化。如果发现某些查询需要创建新索引,但是这个查询又会降低另一些查询的效率,那么应该考虑优化原有的查询,在优化查询和索引找到最佳的平衡,而不是一味追求最完美索引 。
考虑其他常见的WHERE组合列表,并需要了解哪些组合在没有合适索引的情况下会很慢。 (sex, country, age)、(sex, country, region, age)(sex, country, region, city, age)都很常见
这会需要大量的索引。如果想尽量重用索引,可以使用前面提到的IN()技巧
如果没有指定这个字段搜索,就需要定义一个全部国家列表,或者国家的全部地区列表,来确保索引前缀有同样的约束(组合所有国家、地区、性别将会是一个非常大的条件)
为一些生僻的搜索条件(比如has_pictures,eye_color,eduaction)来设计索引
这些列选择性高,使用也不频繁,可以选择忽略,让MySQL多扫描一些额外的行。
或者在age列的前面加上这些列,在查询是使用IN()技巧来处理搜索时没有这些列的场景。
为什么要将age列放在最后?age列有什么特殊的地方? 尽可能让MySQL使用更多的索引列 ,因为查询只能使用索引的最左前缀,直到遇到第一个范围条件 。前面的列都是等于条件,age列则大多是范围条件。
虽然可以用IN()来代替范围查询,例如age IN(18, 19, 20),但不是所有的范围查询都可以转换。
基本原则之二:尽可能将需要做范围查询的列放到索引后面,以便优化器能使用尽可能多的索引列。
5.4.2 避免多个范围条件
假设有一个last_online列并希望通过下面的查询显示在过去几周上线过的用户:
WHERE eye_color IN('brown', 'blue', 'hazel')
AND hair_color IN('black', 'red', 'blonde', 'brown')
AND sex IN("M", "F")
AND last_online > DATE_SUB(NOW(), INTERVAL 7 DAY)
AND age BETWEEN 18 AND 25;
-- MySQL会将age>18和age IN(18,19)都认为是范围查询(通过EXPLAIN查看),但两种访问效率是不同的,因为第二个查询是多个
等值条件查询。对MySQL来说,无法在使用范围查询后面的其他索引列,但对多个等值范围查询没有这个限制。
这个查询有两个范围条件,MySQL无法同时使用它们。 如果无法将age字段转换为一个IN()的列表,并且要求对这两个维度的范围查询的速度很快,很遗憾没有一个直接的办法解决该问题,但可以将其中的一个范围查询转换成一个简单的等值比较:
事先计算好一个active列,这个字段由定时任务来维护。当用户每次登陆时,将对应值设置为1,并且将过去连续7天未登陆的用户的值设置为0。
这个方法可以使用(active, sex, country, age)索引。active并不是完全精确的,因为对这类查询的精度要求并不高。如果需要精确次数,可以把last_online列放到WHERE子句,但不加入到索引中。所以这个查询条件没法使用任何索引,但因为这个条件的过滤性不高,即使在索引中加入该列也没有太大的帮助,或者说缺乏合适的索引对该查询的影响也不明显。
如果用户系统同时看到活跃和不活跃用户,可以在查询中使用IN()列表。另一个可选方案是为不同的组合创建单独的索引,至少要包含(active, sex, country, age),(active, country, age),(sex, country, age)和(country, age),这些索引对某个具体的查询来说可能是更优化的,但是考虑到索引的维护额额外的空间占有代价,并不是一个好策略。
5.4.3 优化排序
对选择性非常低的列,可以增加一些特殊的索引来做排序。例如,可以创建(sex, rating),这个查询同时使用了ORDER BY和LIMIT,如果没有索引会很慢
SELECT FROM profiles WHERE sex="M" ORDER BY rating LIMIT 10
即使有索引,如果用户界面上要翻页,并且翻页翻到比较靠后时查询也可能非常慢:
SELECT FROM profiles WHERE sex="M" ORDER BY rating LIMIT 10000, 10;
无论如何创建索引,这种查询都是严重的问题。因为随着偏移量的增加,MySQL需要花费大量的时间来扫描需要丢弃的数据。反范式化、预先计算和缓存可能是解决这类查询的仅有策略。一个更好的办法是限制用户能够翻页的数量,而实际上这对用户体验的影响并不大,因为用户很少真正在乎搜索结果的第10000页。
优化这类索引另一个较好的办法是使用延迟关联,通过使用覆盖索引查询返回需要的主键,再根据这些主键关联原表获得需要的行。这可以减少MySQL扫描那些需要丢弃的行数。
SELECT FROM profiles INNER JOIN (
SELECT FROM profiles
WHERE sex="M" ORDER BY rating LIMIT 10000, 10
) AS x USING();
5.5 维护和索引表
维护表的三个目的:找到并修复损坏的表,维护准确的索引统计信息,减少碎片
5.5.1 找到并修复顺坏的表
损坏的索引会导致查询返回错误的结果或莫须有的主键冲突问题,严重时还会导致数据库崩溃。
尝试运行CHECK TABLE
来检查是否发生了表损坏(注意有些引擎不支持该命令),通常能够找出大多数的表和索引的错误。
修复表错误的办法:
可以使用REPAIR TABLE
来修复损坏的表(注意有些引擎不支持该命令)。
如果存储引擎不支持REPAIR TABLE
,也可通过一个不做任何操作的ALTER来重建表,如修改表的存储引擎为当前引擎:ALTER TABLE innodb_dbl ENGINE=INNODB;
将数据导出一份,然后再重新导入。
使用第三方工具
如果损坏的是系统区域,或者是表的"行数据"区域,而不是索引,那么之前的办法就没有用了。只能从备份中恢复表,或者尝试从损坏的数据文件中尽可能恢复数据。
如果InnoDB引擎的表出现了损坏,那么一定是发现了严重的错误,需要立刻调查下原因。因为InnoDB的设计一般不会出现损坏。如果发生损坏,可能是数据库的硬件问题,或者在MySQL外部操作了数据文件,亦或是InnoDB的缺陷(不太可能)。不存在任何查询让InnoDB损坏。
如果出现了数据损坏,最重要的是找出原因,而不是简单的修复,否则很有可能会不断的损坏。可以通过设置innodb_force_recovery参数进入InnoDB的强制恢复数据模式来修复数据。
5.5.2 更新索引统计信息
MySQL的查询优化器通过两个API来了解存储引擎的索引值分布信息:
records_in_range(),通过传入两个边界值获取在这个范围大概有多少条记录。对某些存储引擎如MyISAM返回精确值,对InnoDB返回一个估算值。
info(),返回各种类型的数据,包括索引的基数(每个键值有多少条记录)
如果存储引擎向优化器提供的扫描行数信息是不准确的数据,或者执行计划本身太复杂而无法精确地获取各个阶段匹配的行数,那么优化器会使用索引统计信息来估算扫描行数。
MySQL优化器使用的是基于成本的模型,而衡量成本的主要指标就是一个查询需要扫描多少行。如果表没有统计信息,或者统计信息不准确,优化器很可能做出错误的决定。通过运行ANALYZE TABLE来重新生成统计信息解决这个问题。而每种存储引擎实现的统计信息的方式不同,需要进行ANALYZE TABLE的频率和每次运行的成本也不同:
Memory引擎根本不存储索引统计信息
MyISAM将索引统计信息存储在磁盘中,ANALYZE TABLE需要进行一次全索引扫描来计算索引基数,在整个过程中需要锁表。
直到MySQL5.5版本,InnoDB也不在磁盘存储索引统计信息,而是通过随机的索引访问进行评估并将其存储在内存中。
使用SHOW INDEX FROM table;
命令来查看索引的基数(cadinality)。基数显示了存储引擎估算索引列有多少个不同的取值。在MySQL5.0及以后的版本,可以通过INFORMATION_SCHEMA.STATISTICS
表很方便地查询到这些信息,不过如果服务器的库表非常多,从这里获取元数据的速度会非常慢,而且会给MySQL带来额外的压力。
InnoDB的统计信息:
该引擎通过抽样的方式来计算统计信息,首先随机地读取少量的索引页面,然后以此为样本计算索引的统计信息。老版本中样本页数是8,新版本可以设置innodb_stats_sample_pages
来设置样本页的数量。理论上越大的值可以帮助生成更准确的索引信息,特别是对某些超大数据表来说。
会在表首次打开,或者执行ANALYZE TABLE
,抑或表的大小发生非常大的变化(该变化超过十六分之一或者新插入20亿行)的时候计算索引的统计信息。
会在打开某些INFORMATION_SCHEMA
表,或者使用SHOW TABLE STATUS和SHOW INDEX
,抑或MySQL客户端开启自动补全功能的时候都会触发索引统计信息的更新。 如果服务器上有大量的数据,可能会导致严重的问题,尤其是IO比较慢的时候,客户端或者监控程序触发索引信息采样更新时可能会导致大量的锁,并给服务器带来额外的压力。可以关闭innodb_stats_on_metadata
参数来避免上面提到的问题。
5.5.3 减少索引和数据的碎片
索引碎片化 :
B-Tree索引可能会碎片化,这会降低查询的效率。碎片化的索引可能会以很差或者无序的方式存储在磁盘上。
根据设计,B-Tree需要随机磁盘访问才能定位到叶子页,所以随机访问是不可避免的。然而,如果叶子页在物理分布上是顺序且紧密的,那么查询的性能就会更好。否则对于范围查询、索引覆盖扫描等操作来说,速度可能会降低很多倍;对于索引覆盖扫描这一点更明显
表的数据存储碎片化 (比索引碎片化更加复杂): 类型:
行碎片(Row fragmentation):数据行被存储为多个地方的多个片段中。及时查询只从索引中访问一行记录,也会导致性能下降。
行间碎片(Intra-row fragmentation):指逻辑上顺序的页,或者行在磁盘上不是顺序存储的。行间碎片对诸如全表扫描和聚簇索引扫描之类的操作有很大的影响,因为这些操作原本能够从磁盘上的顺序存储的数据收益。
剩余空间碎片(Free space fragmentation):数据页中有大量的空余空间。这会导致服务器读取大量不需要的数据,造成浪费。
对MyISAM表,这三类碎片化都可能发生;但InnoDB不会出现短小的行碎片,它会移动短小的行并重写到一个片段中 。
重新整理数据方式 :
OPTIMIZE TABLE
导出再导入
排序算法重建索引(针对MyISAM)
“在线”添加和删除索引的功能,可以通过先删除,然后在重新创建索引来消除索引碎片(针对最新版本InnoDB)
通过一个不做任何操作的ALTER TABLE ENGINE = ;来重建表(针对不支持OPTIMIZE TABLE
的引擎)
应该通过一些实际测量而不是随意假设来确定是否需要消除索引和表的碎片化,还要考虑数据是否已达到稳定状态 (如果进行碎片整理将数据压缩到一起,可能会导致后续的更新操作触发一系列的页分裂和重组,对性能造成不良的影响直到数据达到新的稳定状态)
5.6总结
MySQL和存储引擎访问数据的方式,加上索引的特性,使得索引成为一个影响数据访问的有利而灵活的工作(无论数据是在磁盘还是在内存中)
大多数情况下都会使用B-Tree索引,其他类型的索引大多只适用于特殊目的。
选择索引和编写利用这些索引的查询时,有如下三个原则始终需要记住 :
单行访问是很慢的 。如果服务器从存储中读取一个数据块只是为了获取其中的一行,那么就浪费了很多工作。最好的读取的块中能包含尽可能多需要的行。使用索引可以创建位置引用提高效率。
按顺序访问范围数据是很快的 。有两个原因:顺序IO不需要多次磁盘寻道而比随机IO快很多;如果服务器能够按需要的顺序读取数据,就不再需要额外的排序操作,并且GROUP BY
查询也无须再做排序和将行按组进行聚合计算。
索引覆盖查询是很快的 。如果一个索引包含了查询需要的所有列,那么存储引擎就不需要再回表查找行,避免了大量的单行访问。
编写查询语句应该尽可能选择合适的索引以避免单行查找,尽可能地使用数据原生顺序而避免额外的数据排序操作,并尽可能使用索引覆盖查询。
对某些查询不可能创建一个“三星”索引,必须要有所取舍,或者寻求替代策略(例如反范式话、或者提前计算汇总表)
理解索引的工作原理来创建最适合的索引
判断为一个系统创建的索引的合理性:按响应时间对查询进行分析。
找出那些消耗时间最长的或给服务器带来最大压力的查询
检查这些查询的schema,SQL和索引结构
判断是否有查询扫描了太多的行,是否做了很多额外的排序或者使用了临时表,是否使用随机IO访问数据,或者是有太多回表查询那些不在索引中的列的操作。
如果一个查询无法从所有可能的索引中获益,则应该看看是否可以创建一个更合适的索引来提升性能。如果不行,也要尝试是否可以重写该查询,将其转化成一个能够高效利用现有索引或者新创建索引的查询。
你可能感兴趣的:(数据库)
Google earth studio 简介
陟彼高冈yu
旅游
GoogleEarthStudio是一个基于Web的动画工具,专为创作使用GoogleEarth数据的动画和视频而设计。它利用了GoogleEarth强大的三维地图和卫星影像数据库,使用户能够轻松地创建逼真的地球动画、航拍视频和动态地图可视化。网址为https://www.google.com/earth/studio/。GoogleEarthStudio是一个基于Web的动画工具,专为创作使用G
关于提高复杂业务逻辑代码可读性的思考
编程经验分享
开发经验 java 数据库 开发语言
目录前言需求场景常规写法拆分方法领域对象总结前言实际工作中大部分时间都是在写业务逻辑,一般都是三层架构,表示层(Controller)接收客户端请求,并对入参做检验,业务逻辑层(Service)负责处理业务逻辑,一般开发都是在这一层中写具体的业务逻辑。数据访问层(Dao)是直接和数据库交互的,用于查数据给业务逻辑层,或者是将业务逻辑层处理后的数据写入数据库。简单的增删改查接口不用多说,基本上写好一
SQL Server_查询某一数据库中的所有表的内容
qq_42772833
SQL Server 数据库 sqlserver
1.查看所有表的表名要列出CrabFarmDB数据库中的所有表(名),可以使用以下SQL语句:USECrabFarmDB;--切换到目标数据库GOSELECTTABLE_NAMEFROMINFORMATION_SCHEMA.TABLESWHERETABLE_TYPE='BASETABLE';对这段SQL脚本的解释:SELECTTABLE_NAME:这个语句的作用是从查询结果中选择TABLE_NAM
深入理解 MultiQueryRetriever:提升向量数据库检索效果的强大工具
nseejrukjhad
数据库 python
深入理解MultiQueryRetriever:提升向量数据库检索效果的强大工具引言在人工智能和自然语言处理领域,高效准确的信息检索一直是一个关键挑战。传统的基于距离的向量数据库检索方法虽然广泛应用,但仍存在一些局限性。本文将介绍一种创新的解决方案:MultiQueryRetriever,它通过自动生成多个查询视角来增强检索效果,提高结果的相关性和多样性。MultiQueryRetriever的工
MongoDB Oplog 窗口
喝醉酒的小白
MongoDB 运维
在MongoDB中,oplog(操作日志)是一个特殊的日志系统,用于记录对数据库的所有写操作。oplog允许副本集成员(通常是从节点)应用主节点上已经执行的操作,从而保持数据的一致性。它是MongoDB副本集实现数据复制的基础。MongoDBOplog窗口oplog窗口是指在MongoDB副本集中,从节点可以用来同步数据的时间范围。这个窗口通常由以下因素决定:Oplog大小:oplog的大小是有限
python os 环境变量
CV矿工
python 开发语言 numpy
环境变量:环境变量是程序和操作系统之间的通信方式。有些字符不宜明文写进代码里,比如数据库密码,个人账户密码,如果写进自己本机的环境变量里,程序用的时候通过os.environ.get()取出来就行了。os.environ是一个环境变量的字典。环境变量的相关操作importos"""设置/修改环境变量:os.environ[‘环境变量名称’]=‘环境变量值’#其中key和value均为string类
【PG】常见数据库、表属性设置
江无羡
数据库
PG的常见属性配置方法数据库复制、备份相关表的复制标识单表操作批量表操作链接数据库复制、备份相关表的复制标识单表操作通过ALTER语句单独更改一张表的复制标识。ALTERTABLE[tablename]REPLICAIDENTITYFULL;批量表操作通过代码块的方式,对某个schema中的所有表一起更新其复制标识。SELECTtablename,CASErelreplidentWHEN'd'TH
nosql数据库技术与应用知识点
皆过客,揽星河
NoSQL nosql 数据库 大数据 数据分析 数据结构 非关系型数据库
Nosql知识回顾大数据处理流程数据采集(flume、爬虫、传感器)数据存储(本门课程NoSQL所处的阶段)Hdfs、MongoDB、HBase等数据清洗(入仓)Hive等数据处理、分析(Spark、Flink等)数据可视化数据挖掘、机器学习应用(Python、SparkMLlib等)大数据时代存储的挑战(三高)高并发(同一时间很多人访问)高扩展(要求随时根据需求扩展存储)高效率(要求读写速度快)
insert into select 主键自增_mybatis拦截器实现主键自动生成
weixin_39521651
insert into select 主键自增 mybatis delete返回值 mybatis insert返回主键 mybatis insert返回对象 mybatis plus insert返回主键 mybatis plus 插入生成id
前言前阵子和朋友聊天,他说他们项目有个需求,要实现主键自动生成,不想每次新增的时候,都手动设置主键。于是我就问他,那你们数据库表设置主键自动递增不就得了。他的回答是他们项目目前的id都是采用雪花算法来生成,因此为了项目稳定性,不会切换id的生成方式。朋友问我有没有什么实现思路,他们公司的orm框架是mybatis,我就建议他说,不然让你老大把mybatis切换成mybatis-plus。mybat
关于Mysql 中 Row size too large (> 8126) 错误的解决和理解
秋刀prince
mysql mysql 数据库
提示:啰嗦一嘴,数据库的任何操作和验证前,一定要记得先备份!!!不会有错;文章目录问题发现一、问题导致的可能原因1、页大小2、行格式2.1compact格式2.2Redundant格式2.3Dynamic格式2.4Compressed格式3、BLOB和TEXT列二、解决办法1、修改页大小(不推荐)2、修改行格式3、修改数据类型为BLOB和TEXT列4、其他优化方式(可以参考使用)4.1合理设置数据
Java爬虫框架(一)--架构设计
狼图腾-狼之传说
java 框架 java 任务 html解析器 存储 电子商务
一、架构图那里搜网络爬虫框架主要针对电子商务网站进行数据爬取,分析,存储,索引。爬虫:爬虫负责爬取,解析,处理电子商务网站的网页的内容数据库:存储商品信息索引:商品的全文搜索索引Task队列:需要爬取的网页列表Visited表:已经爬取过的网页列表爬虫监控平台:web平台可以启动,停止爬虫,管理爬虫,task队列,visited表。二、爬虫1.流程1)Scheduler启动爬虫器,TaskMast
MongoDB知识概括
GeorgeLin98
持久层 mongodb
MongoDB知识概括MongoDB相关概念单机部署基本常用命令索引-IndexSpirngDataMongoDB集成副本集分片集群安全认证MongoDB相关概念业务应用场景:传统的关系型数据库(如MySQL),在数据操作的“三高”需求以及应对Web2.0的网站需求面前,显得力不从心。解释:“三高”需求:①Highperformance-对数据库高并发读写的需求。②HugeStorage-对海量数
Mongodb Error: queryTxt ETIMEOUT xxxx.wwwdz.mongodb.net
佛一脚
error react mongodb 数据库
背景每天都能遇到奇怪的问题,做个记录,以便有缘人能得到帮助!换了一台电脑开发nextjs程序。需要连接mongodb数据,对数据进行增删改查。上一台电脑好好的程序,新电脑死活连不上mongodb数据库。同一套代码,没任何修改,搞得我怀疑人生了,打开浏览器进入mongodb官网毫无问题,也能进入线上系统查看数据,网络应该是没问题。于是我尝试了一下手机热点,这次代码能正常跑起来,连接数据库了!!!是不
入门MySQL——查询语法练习
K_un
前言:前面几篇文章为大家介绍了DML以及DDL语句的使用方法,本篇文章将主要讲述常用的查询语法。其实MySQL官网给出了多个示例数据库供大家实用查询,下面我们以最常用的员工示例数据库为准,详细介绍各自常用的查询语法。1.员工示例数据库导入官方文档员工示例数据库介绍及下载链接:https://dev.mysql.com/doc/employee/en/employees-installation.h
博客网站制作教程
2401_85194651
java maven
首先就是技术框架:后端:Java+SpringBoot数据库:MySQL前端:Vue.js数据库连接:JPA(JavaPersistenceAPI)1.项目结构blog-app/├──backend/│├──src/main/java/com/example/blogapp/││├──BlogApplication.java││├──config/│││└──DatabaseConfig.java
ubuntu安装wordpress
lissettecarlr
1安装nginx网上安装方式很多,这就就直接用apt-get了apt-getinstallnginx不用启动啥,然后直接在浏览器里面输入IP:80就能看到nginx的主页了。如果修改了一些配置可以使用下列命令重启一下systemctlrestartnginx.service2安装mysql输入安装前也可以更新一下软件源,在安装过程中将会让你输入数据库的密码。sudoapt-getinstallmy
深入浅出 -- 系统架构之负载均衡Nginx的性能优化
xiaoli8748_软件开发
系统架构 系统架构 负载均衡 nginx
一、Nginx性能优化到这里文章的篇幅较长了,最后再来聊一下关于Nginx的性能优化,主要就简单说说收益最高的几个优化项,在这块就不再展开叙述了,毕竟影响性能都有多方面原因导致的,比如网络、服务器硬件、操作系统、后端服务、程序自身、数据库服务等,对于性能调优比较感兴趣的可以参考之前《JVM性能调优》中的调优思想。优化一:打开长连接配置通常Nginx作为代理服务,负责分发客户端的请求,那么建议开启H
【RabbitMQ 项目】服务端:数据管理模块之绑定管理
月夜星辉雪
rabbitmq 分布式
文章目录一.编写思路二.代码实践一.编写思路定义绑定信息类交换机名称队列名称绑定关键字:交换机的路由交换算法中会用到没有是否持久化的标志,因为绑定是否持久化取决于交换机和队列是否持久化,只有它们都持久化时绑定才需要持久化。绑定就好像一根绳子,两端连接着交换机和队列,当一方不存在,它就没有存在的必要了定义绑定持久化类构造函数:如果数据库文件不存在则创建,打开数据库,创建binding_table插入
计算机毕业设计PHP仓储综合管理系统(源码+程序+VUE+lw+部署)
java毕设程序源码王哥
php 课程设计 vue.js
该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流项目运行环境配置:phpStudy+Vscode+Mysql5.7+HBuilderX+Navicat11+Vue+Express。项目技术:原生PHP++Vue等等组成,B/S模式+Vscode管理+前后端分离等等。环境需要1.运行环境:最好是小皮phpstudy最新版,我们在这个版本上开发的。其他版本理论上也可以。2.开发
3.增删改查--连接查询
问女何所忆
关系型数据库的一个特点就是,多张表之间存在关系,以致于我们可以连接多张表进行查询操作,所以连接查询会是关系型数据库中最常见的操作。连接查询主要分为三种,交叉连接、内连接和外连接,我们一个个说。1、交叉连接交叉连接其实连接查询的第一个阶段,它简单表现为两张表的笛卡尔积形式,具体例子:如果你没学过数学中的笛卡尔积概念,你可以这样简单的理解这里的交叉连接:两张表的交叉连接就是一个连接合并的过程,T1表中
docker from指令的含义_多个FROM-含义
weixin_39722188
docker from指令的含义
小编典典什么是基本图片?一组文件,加上EXPOSE端口ENTRYPOINT和CMD。您可以添加文件并基于该基础图像构建新图像,Dockerfile并以FROM指令开头:后面提到的图像FROM是新图像的“基础图像”。这是否意味着如果我neo4j/neo4j在FROM指令中声明,则在运行映像时,neo数据库将自动运行并且可在端口7474的容器中使用?仅当您不覆盖CMD和时ENTRYPOINT。但是图像
Redis:缓存击穿
我的程序快快跑啊
缓存 redis java
缓存击穿(热点key):部分key(被高并发访问且缓存重建业务复杂的)失效,无数请求会直接到数据库,造成巨大压力1.互斥锁:可以保证强一致性线程一:未命中之后,获取互斥锁,再查询数据库重建缓存,写入缓存,释放锁线程二:查询未命中,未获得锁(已由线程一获得),等待一会,缓存命中互斥锁实现方式:redis中setnxkeyvalue:改变对应key的value,仅当value不存在时执行,以此来实现互
mysql学习教程,从入门到精通,TOP 和MySQL LIMIT 子句(15)
知识分享小能手
大数据 数据库 MySQL mysql 学习 oracle 数据库 开发语言 adb 大数据
1、TOP和MySQLLIMIT子句内容在SQL中,不同的数据库系统对于限制查询结果的数量有不同的实现方式。TOP关键字主要用于SQLServer和Access数据库中,而LIMIT子句则主要用于MySQL、PostgreSQL(通过LIMIT/OFFSET语法)、SQLite等数据库中。下面将分别详细介绍这两个功能的语法、语句以及案例。1.1、TOP子句(SQLServer和Access)1.1
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your
†徐先森®
Oracle数据库 Web相关 错误集
createtablestudents(idintunsignedprimarykeyauto_increment,namevarchar(50)notnull,ageintunsigned,highdecimal(3,2),genderenum('男','女','中性','保密','妖')default'保密',cls_idintunsigned);在对数据库插入如上带有中文带有默认值的字段的时
Redis 有哪些危险命令?如何防范?
花小疯
redis 缓存 数据库 危险命令 大数据
Redis有哪些危险命令?Redis的危险命令主要有以下几个:1.keys客户端可查询出所有存在的键。2.flushdb删除Redis中当前所在数据库中的所有记录,并且此命令从不会执行失败。3.flushall删除Redis中所有数据库中的所有记录,不止是当前所在数据库,并且此命令从不会执行失败。4.config客户端可修改Redis配置。怎么禁用和重命名危险命令?看下redis.conf默认配置
【Golang】 Golang 的 GORM 库中的 Rows 函数
不爱洗脚的小滕
golang 开发语言 后端
文章目录前言一、Rows函数解释二、代码实现三、总结前言在使用Go语言进行数据库操作时,GORM(GoObject-RelationalMapping)库是一个常用的工具。它提供了一种简洁和强大的方式来处理数据库操作。本文将介绍GORM库中的Rows函数,这是一个用于执行原生SQL查询并返回结果的函数。一、Rows函数解释在GORM库中,Rows函数用于执行原生SQL查询并返回*sql.Rows结
接口测试如何设计测试用例
李蕴Ronnie
接口测试用例设计方式针对每个必填参数,都设计一条参数为空的测试用例必填参数不存在传的参数值在数据库中不存在添加数据接口,传入已有的数据重复添加编辑数据接口,各个字段分别编辑,合并编辑参数数据类型限制,针对每个参数设计一条参数值类型不符合的逆向用例参数自身取值范围,针对所有参数,设计一条每个参数值在取值范围内最大值的正向测试用例是否满足前提条件(token、headers),几个前提条件几条用例针对
Hadoop架构
henan程序媛
hadoop 大数据 分布式
一、案列分析1.1案例概述现在已经进入了大数据(BigData)时代,数以万计用户的互联网服务时时刻刻都在产生大量的交互,要处理的数据量实在是太大了,以传统的数据库技术等其他手段根本无法应对数据处理的实时性、有效性的需求。HDFS顺应时代出现,在解决大数据存储和计算方面有很多的优势。1.2案列前置知识点1.什么是大数据大数据是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的大量数据集合,
非关系型数据库
天秤-white
nosql
一、为什么要用Nosql1.单机MySQL的时代。一个基本的网站访问量一般不会太大,单个数据库完全足够。那时候更多使用的静态网页html,服务器根本没有太大压力。这时候网站的瓶颈是什么?-数据量如果太大,一个机器放不下。-数据量太大需要建立数据的索引(B+Tree),一个服务器内存放不下。-访问量读写混合,一个服务器承受不了。2.memcached缓存+MySQL+垂直拆分(读写分离)。网站80%
六、全局锁和表锁:给表加个字段怎么有这么多阻碍
nieniemin
数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则的重要数据结构。根据加锁的范围,MySQL里面的锁大致可以分成全局锁、表级锁和行锁三类。6.1全局锁全局锁就是对整个数据库实例加锁。MySQL提供了一个加全局读锁的方法,命令是Flushtableswithreadlock(FTWRL)。当你需要让整个库处于
[星球大战]阿纳金的背叛
comsci
本来杰迪圣殿的长老是不同意让阿纳金接受训练的.........
但是由于政治原因,长老会妥协了...这给邪恶的力量带来了机会
所以......现代的地球联邦接受了这个教训...绝对不让某些年轻人进入学院
看懂它,你就可以任性的玩耍了!
aijuans
JavaScript
javascript作为前端开发的标配技能,如果不掌握好它的三大特点:1.原型 2.作用域 3. 闭包 ,又怎么可以说你学好了这门语言呢?如果标配的技能都没有撑握好,怎么可以任性的玩耍呢?怎么验证自己学好了以上三个基本点呢,我找到一段不错的代码,稍加改动,如果能够读懂它,那么你就可以任性了。
function jClass(b
Java常用工具包 Jodd
Kai_Ge
java jodd
Jodd 是一个开源的 Java 工具集, 包含一些实用的工具类和小型框架。简单,却很强大! 写道 Jodd = Tools + IoC + MVC + DB + AOP + TX + JSON + HTML < 1.5 Mb
Jodd 被分成众多模块,按需选择,其中
工具类模块有:
jodd-core &nb
SpringMvc下载
120153216
springMVC
@RequestMapping(value = WebUrlConstant.DOWNLOAD)
public void download(HttpServletRequest request,HttpServletResponse response,String fileName) {
OutputStream os = null;
InputStream is = null;
Python 标准异常总结
2002wmj
python
Python标准异常总结
AssertionError 断言语句(assert)失败 AttributeError 尝试访问未知的对象属性 EOFError 用户输入文件末尾标志EOF(Ctrl+d) FloatingPointError 浮点计算错误 GeneratorExit generator.close()方法被调用的时候 ImportError 导入模块失
SQL函数返回临时表结构的数据用于查询
357029540
SQL Server
这两天在做一个查询的SQL,这个SQL的一个条件是通过游标实现另外两张表查询出一个多条数据,这些数据都是INT类型,然后用IN条件进行查询,并且查询这两张表需要通过外部传入参数才能查询出所需数据,于是想到了用SQL函数返回值,并且也这样做了,由于是返回多条数据,所以把查询出来的INT类型值都拼接为了字符串,这时就遇到问题了,在查询SQL中因为条件是INT值,SQL函数的CAST和CONVERST都
java 时间格式化 | 比较大小| 时区 个人笔记
7454103
java eclipse tomcat c MyEclipse
个人总结! 不当之处多多包含!
引用 1.0 如何设置 tomcat 的时区:
位置:(catalina.bat---JAVA_OPTS 下面加上)
set JAVA_OPT
时间获取Clander的用法
adminjun
Clander 时间
/**
* 得到几天前的时间
* @param d
* @param day
* @return
*/
public static Date getDateBefore(Date d,int day){
Calend
JVM初探与设置
aijuans
java
JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台
SQL中ON和WHERE的区别
avords
SQL中ON和WHERE的区别
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 www.2cto.com 在使用left jion时,on和where条件的区别如下: 1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
说说自信
houxinyou
工作 生活
自信的来源分为两种,一种是源于实力,一种源于头脑.实力是一个综合的评定,有自身的能力,能利用的资源等.比如我想去月亮上,要身体素质过硬,还要有飞船等等一系列的东西.这些都属于实力的一部分.而头脑不同,只要你头脑够简单就可以了!同样要上月亮上,你想,我一跳,1米,我多跳几下,跳个几年,应该就到了!什么?你说我会往下掉?你笨呀你!找个东西踩一下不就行了吗?
无论工作还
WEBLOGIC事务超时设置
bijian1013
weblogic jta 事务超时
系统中统计数据,由于调用统计过程,执行时间超过了weblogic设置的时间,提示如下错误:
统计数据出错!
原因:The transaction is no longer active - status: 'Rolling Back. [Reason=weblogic.transaction.internal
两年已过去,再看该如何快速融入新团队
bingyingao
java 互联网 融入 架构 新团队
偶得的空闲,翻到了两年前的帖子
该如何快速融入一个新团队,有所感触,就记下来,为下一个两年后的今天做参考。
时隔两年半之后的今天,再来看当初的这个博客,别有一番滋味。而我已经于今年三月份离开了当初所在的团队,加入另外的一个项目组,2011年的这篇博客之后的时光,我很好的融入了那个团队,而直到现在和同事们关系都特别好。大家在短短一年半的时间离一起经历了一
【Spark七十七】Spark分析Nginx和Apache的access.log
bit1129
apache
Spark分析Nginx和Apache的access.log,第一个问题是要对Nginx和Apache的access.log文件进行按行解析,按行解析就的方法是正则表达式:
Nginx的access.log解析正则表达式
val PATTERN = """([^ ]*) ([^ ]*) ([^ ]*) (\\[.*\\]) (\&q
Erlang patch
bookjovi
erlang
Totally five patchs committed to erlang otp, just small patchs.
IMO, erlang really is a interesting programming language, I really like its concurrency feature.
but the functional programming style
log4j日志路径中加入日期
bro_feng
java log4j
要用log4j使用记录日志,日志路径有每日的日期,文件大小5M新增文件。
实现方式
log4j:
<appender name="serviceLog"
class="org.apache.log4j.RollingFileAppender">
<param name="Encoding" v
读《研磨设计模式》-代码笔记-桥接模式
bylijinnan
java 设计模式
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
/**
* 个人觉得关于桥接模式的例子,蜡笔和毛笔这个例子是最贴切的:http://www.cnblogs.com/zhenyulu/articles/67016.html
* 笔和颜色是可分离的,蜡笔把两者耦合在一起了:一支蜡笔只有一种
windows7下SVN和Eclipse插件安装
chenyu19891124
eclipse插件
今天花了一天时间弄SVN和Eclipse插件的安装,今天弄好了。svn插件和Eclipse整合有两种方式,一种是直接下载插件包,二种是通过Eclipse在线更新。由于之前Eclipse版本和svn插件版本有差别,始终是没装上。最后在网上找到了适合的版本。所用的环境系统:windows7JDK:1.7svn插件包版本:1.8.16Eclipse:3.7.2工具下载地址:Eclipse下在地址:htt
[转帖]工作流引擎设计思路
comsci
设计模式 工作 应用服务器 workflow 企业应用
作为国内的同行,我非常希望在流程设计方面和大家交流,刚发现篇好文(那么好的文章,现在才发现,可惜),关于流程设计的一些原理,个人觉得本文站得高,看得远,比俺的文章有深度,转载如下
=================================================================================
自开博以来不断有朋友来探讨工作流引擎该如何
Linux 查看内存,CPU及硬盘大小的方法
daizj
linux cpu 内存 硬盘 大小
一、查看CPU信息的命令
[root@R4 ~]# cat /proc/cpuinfo |grep "model name" && cat /proc/cpuinfo |grep "physical id"
model name : Intel(R) Xeon(R) CPU X5450 @ 3.00GHz
model name :
linux 踢出在线用户
dongwei_6688
linux
两个步骤:
1.用w命令找到要踢出的用户,比如下面:
[root@localhost ~]# w
18:16:55 up 39 days, 8:27, 3 users, load average: 0.03, 0.03, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
放手吧,就像不曾拥有过一样
dcj3sjt126com
内容提要:
静悠悠编著的《放手吧就像不曾拥有过一样》集结“全球华语世界最舒缓心灵”的精华故事,触碰生命最深层次的感动,献给全世界亿万读者。《放手吧就像不曾拥有过一样》的作者衷心地祝愿每一位读者都给自己一个重新出发的理由,将那些令你痛苦的、扛起的、背负的,一并都放下吧!把憔悴的面容换做一种清淡的微笑,把沉重的步伐调节成春天五线谱上的音符,让自己踏着轻快的节奏,在人生的海面上悠然漂荡,享受宁静与
php二进制安全的含义
dcj3sjt126com
PHP
PHP里,有string的概念。
string里,每个字符的大小为byte(与PHP相比,Java的每个字符为Character,是UTF8字符,C语言的每个字符可以在编译时选择)。
byte里,有ASCII代码的字符,例如ABC,123,abc,也有一些特殊字符,例如回车,退格之类的。
特殊字符很多是不能显示的。或者说,他们的显示方式没有标准,例如编码65到哪儿都是字母A,编码97到哪儿都是字符
Linux下禁用T440s,X240的一体化触摸板(touchpad)
gashero
linux ThinkPad 触摸板
自打1月买了Thinkpad T440s就一直很火大,其中最让人恼火的莫过于触摸板。
Thinkpad的经典就包括用了小红点(TrackPoint)。但是小红点只能定位,还是需要鼠标的左右键的。但是自打T440s等开始启用了一体化触摸板,不再有实体的按键了。问题是要是好用也行。
实际使用中,触摸板一堆问题,比如定位有抖动,以及按键时会有飘逸。这就导致了单击经常就
graph_dfs
hcx2013
Graph
package edu.xidian.graph;
class MyStack {
private final int SIZE = 20;
private int[] st;
private int top;
public MyStack() {
st = new int[SIZE];
top = -1;
}
public void push(i
Spring4.1新特性——Spring核心部分及其他
jinnianshilongnian
spring 4.1
目录
Spring4.1新特性——综述
Spring4.1新特性——Spring核心部分及其他
Spring4.1新特性——Spring缓存框架增强
Spring4.1新特性——异步调用和事件机制的异常处理
Spring4.1新特性——数据库集成测试脚本初始化
Spring4.1新特性——Spring MVC增强
Spring4.1新特性——页面自动化测试框架Spring MVC T
配置HiveServer2的安全策略之自定义用户名密码验证
liyonghui160com
具体从网上看
http://doc.mapr.com/display/MapR/Using+HiveServer2#UsingHiveServer2-ConfiguringCustomAuthentication
LDAP Authentication using OpenLDAP
Setting
一位30多的程序员生涯经验总结
pda158
编程 工作 生活 咨询
1.客户在接触到产品之后,才会真正明白自己的需求。
这是我在我的第一份工作上面学来的。只有当我们给客户展示产品的时候,他们才会意识到哪些是必须的。给出一个功能性原型设计远远比一张长长的文字表格要好。 2.只要有充足的时间,所有安全防御系统都将失败。
安全防御现如今是全世界都在关注的大课题、大挑战。我们必须时时刻刻积极完善它,因为黑客只要有一次成功,就可以彻底打败你。 3.
分布式web服务架构的演变
自由的奴隶
linux Web 应用服务器 互联网
最开始,由于某些想法,于是在互联网上搭建了一个网站,这个时候甚至有可能主机都是租借的,但由于这篇文章我们只关注架构的演变历程,因此就假设这个时候已经是托管了一台主机,并且有一定的带宽了,这个时候由于网站具备了一定的特色,吸引了部分人访问,逐渐你发现系统的压力越来越高,响应速度越来越慢,而这个时候比较明显的是数据库和应用互相影响,应用出问题了,数据库也很容易出现问题,而数据库出问题的时候,应用也容易
初探Druid连接池之二——慢SQL日志记录
xingsan_zhang
日志 连接池 druid 慢SQL
由于工作原因,这里先不说连接数据库部分的配置,后面会补上,直接进入慢SQL日志记录。
1.applicationContext.xml中增加如下配置:
<bean abstract="true" id="mysql_database" class="com.alibaba.druid.pool.DruidDataSourc