第五章 创建高性能的索引
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访问数据,或者是有太多回表查询那些不在索引中的列的操作。
如果一个查询无法从所有可能的索引中获益,则应该看看是否可以创建一个更合适的索引来提升性能。如果不行,也要尝试是否可以重写该查询,将其转化成一个能够高效利用现有索引或者新创建索引的查询。
你可能感兴趣的:(数据库)
什么是缓存雪崩?缓存击穿?缓存穿透?分别如何解决?什么是缓存预热?
daixin8848
缓存 redis java 开发语言
缓存雪崩:在一个时间段内,有大量的key过期,或者Redis服务宕机,导致大量的请求到达数据库,带来巨大压力-给key设置不同的TTL、利用Redis集群提高服务的高可用性、添加多级缓存、添加降级流策略缓存击穿:给某一个key设置了过期时间,当key过期的时间,恰好这个时间点有大量的并发请求访问这个key,可能会瞬间把数据库压垮-互斥锁:缓存失败时,只允许一个请求去加载数据并更新缓存,其他请求阻塞
Aop +反射 实现方法版本动态切换
需求分析在做技术选型的时候一直存在着两个声音,mongo作为数据库比较mysql好,mysql做为该数据比mongo好。当然不同数据库都有有着自己的优势,我们在做技术选型的时候无非就是做到对数据库的扬长避短。mysql最大的优势就是支持事务,事务的五大特性保证的业务可靠性,随之而来的就是事务会产生的问题:脏读、幻读、不可重复度,当然我们也会使用不同的隔离级别来解决。(最典型的业务问题:银行存取钱)
MySQL复习题
一.填空题1.关系数据库的标准语言是SQL。2.数据库发展的3个阶段中,数据独立性最高的是阶段数据库系统。3.概念模型中的3种基本联系分别是一对一、一对多和多对多。4.MySQL配置文件的文件名是my.ini或my.cnf。5.在MySQL配置文件中,datadir用于指定数据库文件的保存目录。6.添加IFNOTEXISTS可在创建的数据库已存在时防止程序报错。7.MySQL提供的SHOWCREA
Android GreenDao介绍和Generator生成表对象代码
目录(?)[-]介绍创建工程转载请注明:http://blog.csdn.net/sinat_30276961/article/details/50052109最近无意中发现了GreenDao,然后查看了一些资料后,发现这个数据库框架很适合用,于是乎,查看了官网的api,并自己写了一个小应用总结一下它的使用方法。介绍按照国际惯例,在开篇,总要先介绍一下什么是GreenDao吧。首先需要说明的是Gr
Mac OSX 下的mysql数据库文件存放位置
Bruuuces
mysql mac osx 位置 存放
之前我的mysql的系统数据库里的表被我玩坏了,万般无奈之下只得删除所有mysql的东西重新构建数据库。按照网上搜到的内容删除后重装发现数据库没有什么变化。于是自己在每个可能存放数据库文件的目录查找,最终确认目录位置如下:使用HomeBrew安装为/usr/local/var/mysql使用官方下载的dmg镜像安装为/usr/local/mysql删除这个目录再重新安装mysql就会重新生成系统数
mac升级mysql_Mac OSX下的MySQL数据库升级
weixin_39801714
mac升级mysql
MacOSX下的数据库升级最麻烦的不过权限的问题.本文的MySQL的安装方式为OSX下DMG磁盘镜像的安装方式,MacPorts/Homebrew的方式大同小异.从5.6.17升级到5.7.18安装目录信息ls-al/usr/local|grepmysqllrwxr-xr-x1rootwheel30B52100:39mysql@->mysql-5.6.17-osx10.7-x86_64drwxr-
【MySQL】MySQL数据库如何改名
武昌库里写JAVA
面试题汇总与解析 spring boot vue.js sql java 学习
MySQL建库授权语句https://www.jianshu.com/p/2237a9649ceeMySQL数据库改名的三种方法https://www.cnblogs.com/gomysql/p/3584881.htmlMySQL安全修改数据库名几种方法https://blog.csdn.net/haiross/article/details/51282417MySQL重命名数据库https://
HikariCP调试日志深度解析:生产环境故障排查完全指南
HikariCP调试日志深度解析:生产环境故障排查完全指南更新时间:2025年7月4日|作者:资深架构师|适用版本:HikariCP5.x+|难度等级:中高级前言在生产环境中,数据库连接池往往是系统性能的关键瓶颈。HikariCP作为当前最流行的Java连接池,其调试日志包含了丰富的运行时信息,能够帮助我们快速定位和解决各种连接池相关问题。本文将深入解析HikariCP的日志体系,提供一套完整的故
大学社团管理系统(11831)
codercode2022
java spring boot spring echarts spring cloud sentinel java-rocketmq
有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项目截图有需要的同学,源代码和配套文档领取,加文章最下方的名片哦!
前端数据库:IndexedDB从基础到高级使用指南
文章目录前端数据库:IndexedDB从基础到高级使用指南引言一、IndexedDB概述1.1什么是IndexedDB1.2与其他存储方案的比较二、基础使用2.1打开/创建数据库2.2基本CRUD操作添加数据读取数据更新数据删除数据三、高级特性3.1复杂查询与游标3.2事务高级用法3.3性能优化技巧四、实战案例:构建离线优先的待办事项应用4.1数据库设计4.2同步策略实现五、常见问题与解决方案5.
修改gitlab默认的语言
Victor刘
gitlab
文章目录网上的方法1.采用数据库触发器的方法2.登录pg库2.1查看表2.2创建function2.3创建触发器2.4修改历史数据网上的方法网上修改/opt/gitlab/embedded/service/gitlab-rails/config/application.rb的方法,我试了,没生效,没进一步研究1.采用数据库触发器的方法2.登录pg库su-gitlab-psqlpsql-h/var/
如何在 Ubuntu 24.04 或 22.04 Linux 上安装和运行 Redis 服务器
山岚的运维笔记
Linux 运维及使用 linux 服务器 ubuntu redis 数据库
Redis(RemoteDictionaryServer,远程字典服务器)是一种内存数据结构存储,通常用作NoSQL数据库、缓存和消息代理。它是开源的,因此用户可以免费安装,无需支付任何费用。Redis旨在为需要快速数据访问和低延迟的应用程序提供速度和效率。Redis支持多种数据类型,包括字符串(Strings)、列表(Lists)、集合(Sets)、哈希(Hashes)、有序集合(SortedS
数据库基础概念梳理
22:30Plane-Moon
数据库
1.数据存储类型表(Table):存储结构化数据的标准方式,数据以行和列的形式组织,具有固定的格式。非结构化数据(UnstructuredData):如音频、视频、图片、文本文档等,其格式不固定,不易直接用表存储。2.SQL的核心优势SQL尤其擅长处理和操作存储在表中的结构化数据。2.1数据类型约束(DataTypeConstraints):定义列可存储的数据种类。整数类型:TINYINT(1字节
SQL笔记纯干货
AI入门修炼
oracle 数据库 sql
软件:DataGrip2023.2.3,phpstudy_pro,MySQL8.0.12目录1.DDL语句(数据定义语句)1.1数据库操作语言1.2数据表操作语言2.DML语句(数据操作语言)2.1增删改2.2题2.3备份表3.DQL语句(数据查询语言)3.1查询操作3.2题一3.3题二4.多表详解4.1一对多4.2多对多5.多表查询6.窗口函数7.拓展:upsert8.sql注入攻击演示9.拆表
分布式全局唯一ID生成:雪花算法 vs Redis Increment,怎么选?
雪花算法vsRedisIncrement:分布式全局唯一ID生成方案深度对比在分布式系统开发中,“全局唯一ID”是绕不开的核心问题。无论是分库分表的数据库设计、订单编号的唯一性保证,还是日志追踪的链路标识,都需要一套可靠的ID生成方案。今天我们就来聊聊两种主流方案——雪花算法(Snowflake)和RedisIncrement,并从原理、特性到适用场景,帮你理清如何选择。同时,我们还将对比其他常见
【Druid】学习笔记
fixAllenSun
学习 笔记 oracle
【Druid】学习笔记【一】简介【1】简介【2】数据库连接池(1)能解决的问题(2)使用数据库连接池的好处【3】监控(1)监控信息采集的StatFilter(2)监控不影响性能(3)SQL参数化合并监控(4)执行次数、返回行数、更新行数和并发监控(5)慢查监控(6)Exception监控(7)区间分布(8)内置监控DEMO【4】Druid基本配置参数介绍【5】Druid相比于其他数据库连接池的优点
构建高效的物流车辆定位管理系统
体制教科书
本文还有配套的精品资源,点击获取简介:物流车辆定位管理系统利用信息技术提高物流效率和安全性。通过集成GPS技术进行实时车辆追踪和监控,它提供及时的货物运送和异常处理。系统的关键技术包括GPS车辆定位、C#编程语言、数据库管理、车辆管理、在途情况监控、预警与通知、数据分析与报告、用户界面设计、安全性与隐私保护以及系统集成。这些要素共同保障物流流程的高效、安全和智能化。1.物流车辆定位管理系统的应用与
Spring AI Alibaba 快速入门指南(适合初学者)
会飞的架狗师
AI spring 人工智能 java
如果你是刚接触AI开发或Spring框架的初学者,不用担心,本指南会用简单易懂的语言带你一步步了解并使用SpringAIAlibaba。一、什么是SpringAIAlibaba(小白也能懂)简单来说,SpringAIAlibaba就是一个“工具包”,它把阿里巴巴的AI技术(比如通义千问大模型、向量数据库等)和大家常用的Spring框架“打包”到了一起。**打个比方:**就像你想做蛋糕(开发AI应用
Java朴实无华按天计划从入门到实战(强化速战版-66天)
岫珩
Java 后端 java 开发语言 学习 Java 时间安排 学习计划
致敬读者感谢阅读笑口常开生日快乐⬛早点睡觉博主相关博主信息博客首页专栏推荐活动信息文章目录Java朴实无华按天计划从入门到实战(强化速战版-66天)1.基础(18)1.1JavaSE核心(5天)1.2数据库与SQL(5天)1.3前端基础(8天)2.进阶(17天)2.1JavaWeb核心(5天)2.2Mybatis与Spring全家桶(6天)2.3中间件入门(4天)2.4实践项目(2天)3.高阶(1
企业级RAG的数据方案选择 - 向量数据库、图数据库和知识图谱
南七小僧
AI技术产品经理 网站开发 人工智能 数据库 知识图谱 人工智能
如何为企业RAG选择合适的数据存储方式摘要:本文讨论了矢量数据库、图数据库和知识图谱在解决信息检索挑战方面的重要性,特别是针对企业规模的检索增强生成(RAG)。看看海外人工智能企业Writer是如何利用知识图谱增强企业级RAG。要点概要:矢量数据库高效存储数据,但缺乏上下文和关联信息。图数据库优先考虑数据点之间的关系,受益于关系结构。知识图谱在语义存储方面表现出色,由于其能够编码丰富的上下文信息,
小白学习mysql
阿什么名字不会重复呢
mysql 数据库 大数据 人工智能
推荐自学网站不用下载本地环境带自测头歌https://www.educoder.net✅适合基础小白的MySQL简单实用学习计划总学习时间建议:10~14天,每天1小时左右即可最终目标:掌握基础SQL操作,能完成简单项目需求第1阶段:认识数据库与环境搭建(1~2天)你需要学会:•数据库是什么?SQL是什么?•安装MySQLServer+Navicat(推荐用Navicat可视化工具)✅推荐学习内容
Navicat 全面支持金仓数据库 KingbaseES,为金仓生态圈注入新动能
Navicat中国
Navicat 17 焕新上市 Navicat 免费版 数据库
近日,我们宣布Navicat系列产品全面支持中电科金仓(北京)科技股份有限公司旗下金仓数据库管理系统KingbaseES。KingbaseES是面向全行业、全客户关键应用的企业级大型通用融合数据库产品,适用于事务处理类应用、数据分析类应用、海量时序数据采集检索类应用、要求苛刻的互联网等应用场景。这次合作,不仅是Navicat在数据库管理领域的又一重要里程碑,更凭借卓越的技术为金仓数据库的生态注入新
MYSQL:MySQL 事务隔离级别详解
奋斗的狍子007
MySQL核心知识点 mysql 数据库 java spring 架构 spring boot ide
一、MySQL事务是什么? MySQL事务是一组在数据库中执行的操作,这些操作要么全部成功执行,要么全部不执行,以确保数据库的完整性和一致性。事务的ACID 事务具有四个特征:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持续性(Durability)。这四个特性简称为ACID特性。原子性:事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,
免费版 Navicat Premium Lite 17 下载和使用
曼巴不黑
数据库 navicat navicat免费
>>>>>>下载地址以后不需要再为使用Navicat大费周章了,官网已经提供免费版供个人和初创企业使用,认准NavicatPremiumLite。NavicatPremiumLite是Navicat的精简版,它包含了用户执行主要的基本数据库操作所需的核心功能。它允许你同时连接到各种数据库平台,包括MySQL、PostgreSQL、SQLServer、Oracle、MariaDB、Snowflake
Navicat Premium 17.1 的详细使用教程
春云资源
mysql
下载地址:NavicatPremium17.1最新官方版|春云资源#NavicatPremium17.1功能全解析与使用教程指南在当今数字化的时代,数据库管理的高效性与便捷性成为众多企业和开发者追求的目标。NavicatPremium17.1作为一款备受瞩目的数据库管理工具,以其强大的功能和友好的用户界面脱颖而出。以下将为您详细介绍其使用方法,助力您轻松驾驭数据库管理工作。##一、下载与安装流程开
Navicat Premium for Mac 17.1.10 版本重置方案解析
岑铭恩
NavicatPremiumforMac17.1.10版本重置方案解析背景介绍NavicatPremium是一款广受欢迎的数据库管理工具,其Mac版本在17.1.10版本中采用了新的授权验证机制。许多用户在试用期结束后需要重置试用期,但发现传统的重置方法不再适用。本文将深入分析该版本的重置原理和具体操作方案。技术原理分析NavicatPremium17.1.10forMac版本将授权信息存储在用户
TiDB - 分布式数据库的架构与特性
爽新全效瓷兔膏
本文还有配套的精品资源,点击获取简介:TiDB是一个开源的分布式NewSQL数据库,受到了Google的Spanner/F1系统的启发。它提供水平扩展和强一致性事务,适用于需要高可用性和大规模数据处理的场景。TiDB的核心特点包括其分布式架构,由TiDBServer(SQL层)、PDServer(调度器)和TiKVServer(存储引擎)组成;支持无缝的水平扩展和ACID事务;与MySQL高度兼容
MySQL 数据类型详解
yimeixiaolangzai
MySQL mysql 数据库
在数据库设计和开发中,选择合适的数据类型对于存储和操作数据至关重要。MySQL提供了丰富的数据类型来满足不同的数据存储需求,这些数据类型可以分为数值类型、字符串类型、日期和时间类型,以及二进制类型。本文将详细介绍MySQL中的各类数据类型及其应用场景,帮助你更好地进行数据库设计。1.数值类型数值类型用于存储整数和浮点数,在处理数值运算时,这些数据类型扮演着关键角色。MySQL提供了多种数值类型,以
MySQL数据类型详解
永远是少年啊
MySQL mysql 数据库 database
今天继续给大家介绍MySQL相关内容,本文主要内容是MySQL数据类型。MySQL数据库支持多种数据类型,这些数据类型大致可以分为三类:数值型、字符型和时间型。下面将MySQL的具体数据类型介绍如下:一、数值型类型大小(单位:字节)数值范围(有符号)数值范围(无符号)用途TINYINT1(-128,127)(0,255)微整数型SMALLINT2(-32768,32767)(0,65535)小整数
python3中,pycharm中怎么连接数据库
weixin_33736832
数据库 python 开发工具
因为python3现在还不能直接连接数据库,所有如果想连接,就只能通过以下方法:在APP中的,__init__.py中,添加以下代码就可以:importpymysqlpymysql.install_as_MySQLdb()当然前提是,那就的在setting.py中连接数据库添加所连接的mysql数据库的详细信息,如下:DATABASES={'default':{'ENGINE':'django.d
[星球大战]阿纳金的背叛
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