第五章 创建高性能的索引
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访问数据,或者是有太多回表查询那些不在索引中的列的操作。
如果一个查询无法从所有可能的索引中获益,则应该看看是否可以创建一个更合适的索引来提升性能。如果不行,也要尝试是否可以重写该查询,将其转化成一个能够高效利用现有索引或者新创建索引的查询。
你可能感兴趣的:(数据库)
如何使用 Spring Boot 实现分页和排序
大G哥
spring boot 后端 java spring
在SpringBoot中实现分页和排序通常是通过SpringDataJPA或者SpringDataMongoDB提供的分页功能来完成的。以下是一个基于SpringDataJPA的分页和排序实现的基本步骤。1.添加依赖首先,确保你在pom.xml中包含了SpringDataJPA和数据库驱动的依赖。org.springframework.bootspring-boot-starter-data-jp
自动同步多服务器下SQL脚本3.0
a栋栋栋
遇到的问题 sql 自动化 事务失效
由于上一版发现数据库【MySQL】不支持DML事务回滚,该迭代主要是去兼容这种问题。数据表新增一个completed字段,用来表示当前版本下同步成功的个数。数据表CREATETABLE`auto_sql_version`(`id`intNOTNULLAUTO_INCREMENT,`version`varchar(20)CHARACTERSETutf8mb4COLLATEutf8mb4_0900_a
python高并发访问mysql_Python访问MySQL
阿廖林诺
Python访问数据库作为Python开发工程师,选择哪个数据库呢?当然是MySQL。因为MySQL不仅免费,普及率最高,出了错,可以很容易找到解决方法。而且,围绕MySQL有一大堆监控和运维的工具,安装和使用很方便。使用MySQLMySQL是Web世界中使用最广泛的数据库服务器。SQLite的特点是轻量级、可嵌入,但不能承受高并发访问,适合桌面和移动应用。而MySQL是为服务器端设计的数据库,能
基于ASP.NET校园二手交易网站设计与实现
汐泽学园
asp.net 后端
摘要校园二手交易市场伴随互联网技术的迅猛发展以及校园内资源共享需求的增长而逐渐兴起。基于ASP.NET开发的校园二手交易网站,目的在于为高校师生打造一个便捷、安全且高效的二手物品交易平台。此网站借助ASP.NET技术开展开发工作,并且结合SQLServer数据库来存储数...关键词ASP.NET;校园二手交易;网站设计AbstractWiththerapiddevelopmentofInterne
基于oracle linux的 DBI/DBD 标准化安装文档(二)
文档
一、安装DBIDBI(DatabaseInterface)是perl连接数据库的接口。其是perl连接数据库的最优方法,他支持包括Orcale,Sybase,mysql,db2等绝大多数的数据库,下面将简要介绍其安装方法。1.1解压tar-zxvfDBI-1.616_901.tar.gz1.2安装依赖yuminstallperl-ExtUtils-CBuilderperl-ExtUtils-Mak
基于asp.NET的病历管理系统 (源码+net+vue+部署文档+讲解等)
qq_1406299528
计算机毕业设计 asp asp.net vue.js 后端
收藏关注不迷路!!文末获取源码+数据库感兴趣的可以先收藏起来,还有大家在毕设选题(免费咨询指导选题),项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人文章目录前言程序资料获取一、项目技术二、项目内容和功能介绍三、核心代码数据库参考四、效果图五、资料获取前言博主介绍:✨全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,专注于Java/Python/小程序app/深度学
爬取电影标题、评论、评分(21-11-4)
穆桥
Python爬虫 XPath解析 MySQL数据库 电影信息 疾病数据
功能描述:1、爬取网页1中的电影名称、评分、简介到mysql数据库中。2、爬取网页2中的标题、时间、正文、采集时间到mysql数据库中。使用的技术:requests请求、xpath解析、mysqlxpath解析语法//子孙节点/直接子节点.选取当前节点…选取当前节点的父节点@选取属性通过Python的lxml库,利用XPath进行HTML的解析。scrapy封装了lxml也可以导入scrapy任务
oracle数据库监听日志满了(4G)处理步骤
cyhysr
oracle
现象:系统缓慢,新连接无法连接,执行查看监听状态命令时,响应缓慢且报错。遇到这些现象基本是监听日志已满,达到了4G。具体处理步骤如下:注意:本例为windows服务器,数据库oracle11g1、找到监听日志路径默认监听名为listener,直接在服务器中搜索listener.log文件。如果是windows服务器,且数据库安装在D盘,可参考如下路径:D:\app\Administrator\di
什么是Mybatis?最全的Mybatis知识点整合!
Tyloo_wdnmd
数据库 mybatis java python mysql
什么是Mybatis?最全的Mybatis知识点整合!一、什么是Mybatis?MyBatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去加载驱动、创建连接、创建Statement等繁杂过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。Mybatis可以使用XML或注解来配置和映射原生信息,将POJO映射成数据库中
MyBatis高级查询:一对多查询详解
蓝天资源分享
mybatis tomcat java
MyBatis高级查询:一对多查询详解MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码和手动设置参数以及获取结果集的工作。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(PlainOldJavaObjects,普通的Java对象)映射成数据库中的记录。本文将深入探讨MyBatis中的
Python 爬虫实战:电影评论数据抓取与自然语言处理
西攻城狮北
python 爬虫 开发语言
引言作为一名对电影数据和自然语言处理感兴趣的内容创作者,我决定利用Python爬虫技术抓取IMDb上的电影评论数据,并进行自然语言处理分析。这不仅可以帮助我们了解观众对电影的反馈,还能为电影制作方提供有价值的参考。一、项目背景IMDb(互联网电影数据库)是全球最大的电影数据库,用户可以在上面查看电影信息和用户评论。本项目旨在爬取IMDb上的电影评论,并对评论进行自然语言处理(NLP),以提取情感、
【AI热点】MCP协议深度洞察报告
碣石潇湘无限路
人工智能 php 开发语言
摘要人工智能技术飞速发展,大型语言模型(LLM)如何高效、安全地利用外部数据和工具成为关键问题。模型上下文协议(ModelContextProtocol,简称MCP)是一种由Anthropic于2024年底提出的开放标准协议。它通过统一的客户端-服务器架构,为AI应用与文件系统、数据库、第三方API等外部资源之间提供标准化、安全的双向通信接口。本文将深入解析MCP协议的基本概念和背景、架构设计(通
HIVE开窗函数
Cciccd
sql hive
ETL,SQL面试高频考点——HIVE开窗函数(基础篇)目录标题ETL,SQL面试高频考点——HIVE开窗函数(基础篇)一,窗口函数介绍二,开窗函数三,分析函数分类1,排序分析函数:实列解析对比总结2.聚合分析函数3.用spark自定义HIVE用户自定义函数后续更新中~一,窗口函数介绍窗口函数,也叫OLAP函数(OnlineAnallyticalProcessing,联机分析处理),可以对数据库数
分布式系统中分布式ID生成方案的技术详解
心存の思念
分布式
分布式系统中分布式ID生成方案的技术详解在复杂的分布式系统中,数据被分散存储在不同的节点上,每个节点都有自己独立的数据库。为了保证数据的唯一性和一致性,我们需要为每个数据项生成一个全局唯一的主键ID。本文将详细解析几种常用的分布式ID生成方案,包括它们的工作原理、优缺点以及适用场景。一、分布式系统唯一ID的特点全局唯一性:不能出现重复的ID号,这是最基本的要求。趋势递增:在MySQLInnoDB引
二叉树中两个节点最近公共祖先的查找算法研究
cloudman08
深度优先 算法
目录摘要一、引言二、问题定义三、问题分析3.1二叉树的特性利用3.2暴力搜索的不足四、算法设计4.1递归算法(适用于普通二叉树)4.2迭代算法(适用于二叉搜索树)4.3代码实现(Python)4.4代码解释五、复杂度分析5.1递归算法复杂度(普通二叉树)5.2迭代算法复杂度(二叉搜索树)六、实际应用6.1文件系统目录结构6.2遗传算法中的基因树分析6.3数据库索引结构优化七、结论摘要在二叉树相关算
在线 SQL 转 Python ORM工具
A__tao
sql oracle 数据库
一款高效的在线SQL转PythonORM,支持自动解析SQL语句并生成PythonORM模型代码,适用于数据库管理、后端开发和ORM结构映射。无需手写ORM模型,一键转换SQL结构,提升开发效率,简化数据库操作。gotool
如何进行OceanBase 运维工具的部署和表性能优化
oceanbase
随着OceanBase数据库应用的日益深入,数据量不断攀升,单个表中存储数百万乃至数千万条数据的情况变得愈发普遍。因此,部署专门的运维工具、实施针对性的表性能优化策略,以及加强指标监测工作,都变得更为重要。以下为基于我们的使用场景,所采取的一些部署和优化措施分享。一、OCP部署升级1.OCP升级(1)4.2.1BP1升级到4.2.2,本来以为毫无波澜但是下载完毕一键包并完成前期准备工作启动后发现无
基于oracle linux的 DBI/DBD 标准化安装文档(三)
oracle
一、安装DBIDBI(DatabaseInterface)是perl连接数据库的接口。其是perl连接数据库的最优方法,他支持包括Orcale,Sybase,mysql,db2等绝大多数的数据库,下面将简要介绍其安装方法。1.1解压tar-zxvfDBI-1.616_901.tar.gz1.2安装依赖yuminstallperl-ExtUtils-CBuilderperl-ExtUtils-Mak
HTML5 Web SQL
froginwe11
开发语言
HTML5WebSQL引言随着互联网技术的飞速发展,HTML5作为新一代的网页技术,已经逐渐成为网页开发的主流。在HTML5中,WebSQL是一种轻量级的数据库存储技术,它允许开发者直接在网页中存储数据。本文将详细介绍HTML5WebSQL的概念、特点、应用场景以及使用方法。一、WebSQL概念WebSQL是一种轻量级的数据库存储技术,它允许开发者使用SQL语句在网页中存储数据。WebSQL数据库
向量存储与检索器
小码农0912
AI应用开发 向量存储与检索器 向量存储 检索器 langchain
文章目录向量存储如何创建和查询向量存储相似性搜索按向量进行相似性搜索异步操作检索器如何使用向量存储作为检索器从向量存储创建检索器最大边际相关性检索传递搜索参数相似性得分阈值检索指定前k案例案例1案例2langchain支持从向量数据库和其他来源检索数据,以便与LLM(大型语言模型)工作流程集成。它们对于应用程序来说非常重要,这些应用程序需要获取数据以作为模型推理的一部分进行推理,就像检索增强生成(
网络安全难学吗?学网络安全的好处是什么?
网络安全(king)
网络安全 网络工程师 黑客 web安全 网络 安全
在这个高度依赖于网络的时代,网络安全已经成为我们工作和生活中不可或缺的一部分,更是0基础转行IT的首选,可谓是前景好、需求大,在企业当中也属于双高职位,地位高、薪资高,而且入门门槛低,那么网络安全难学吗?学网络安全的好处是什么?以下是详细内容介绍。网络安全难学吗?学习网络安全需要循序渐进,由浅入深。其实网络安全本身的知识并不是很难,但是需要学习的内容有很多,比如包括Linux、数据库、渗透测试、等
2024最新版头歌实践教学平台数据库原理与应用实训答案
泠波
数据库
实训一:数据定义和操纵(4课时)初识MySQL数据库第1关:创建数据库mysql-uroot-p123123-h127.0.0.1createdatabaseMyDb;showdatabases;第2关:创建表mysql-uroot-p123123-h127.0.0.1createdatabaseTestDb;createtablet_emp(idint,namevarchar(32),deptI
物联网设备数据流转之搭建环境:开源高性能分布式支持SQL的时序数据库TDengine
Heartsuit
时序数据库 物联网 分布式 TDengine 涛思数据
背景我们的项目涉及物联网相关业务,由于一开始的年少无知,传感器数据采用了MySQL进行存储,经过近两年的数据累积,目前几个核心表,单表数据已过亿,虽然通过索引优化、SQL优化以及读写分离等措施,勉强满足基本的查询,能在秒级给出数据;但是一方面当前MySQL数据表索引的大小甚至超过了数据大小,这样下去肯定不行;另一方面来自于前端感知设备的数据量还在持续增加,当面对用户多维度的统计需求,在实现上、效率
TDengine 使用教程:从入门到实践
遇见伯灵说
tdengine 大数据 时序数据库
TDengine是一款专为物联网(IoT)和大数据实时分析设计的时序数据库。它能够高效地处理海量的时序数据,并提供低延迟、高吞吐量的性能表现。在本文中,我们将带领大家从TDengine的安装、基本操作到一些高级功能,帮助你快速上手。1.TDengine简介TDengine是一个高效的时序数据存储解决方案,支持高并发写入和快速的实时分析。它适用于各种物联网应用场景,如传感器数据监控、日志数据处理等。
Python csv库
xiaoming0018
python python 开发语言
CSV文件又称为逗号分隔值文件,是一种通用的、相对简单的文件格式,用以存储表格数据,包括数字或者字符。CSV是电子表格和数据库中最常见的输入、输出文件格式,可参考《CSV介绍》。通过爬虫将数据抓取的下来,然后把数据保存在文件,或者数据库中,这个过程称为数据的持久化存储。本节介绍Python内置模块CSV的读写操作。CSV库Python中集成了专用于处理csv文件的库,名为:csv。csv库中有4个
leetcode-sql数据库面试题冲刺(高频SQL五十题)
我想吃烤肉肉
sql 测试面试 数据库 leetcode sql
题目:1633.各赛事的用户注册率用户表:Users±------------±--------+|ColumnName|Type|±------------±--------+|user_id|int||user_name|varchar|±------------±--------+user_id是该表的主键(具有唯一值的列)。该表中的每行包括用户ID和用户名。注册表:Register±---
系统架构设计师——架构风格
庄隐
# 系统架构设计师 系统架构 架构 系统架构设计师
概述软件体系结构风格是指在软件架构设计中,针对特定应用领域所采用的一套惯用模式,这些模式定义了系统的组织方式。以下是对软件体系结构风格的详细解析:1.体系结构风格的概念目的:简化设计过程,提高设计的重用性和可维护性。特点:每种风格都有其特定的适用范围和优势,适用于不同的应用场景和需求。2.词汇表构件:系统中的基本功能单元,如客户端、服务器、数据库等。连接件:用于构件间交互的桥梁,如管道、总线、过滤
跟着黑马学MySQL基础篇笔记(4)-多表查询
小杜不吃糖
mysql 笔记
37.多表查询-多表关系介绍多表关系概述项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:一对多(多对一)多对多一对一一对多(多对一)案例:部门与员工的关系关系:一个部门对应多个员工,一个员工对应一个部门实现:在多的一方建立外键,指向一的一方的主键多对多案例:学生与课程的关系一个学生
如何在飞牛云NAS快速使用Docker打造稳定安全的本地网站并对外可见
gkfkfhk
docker 安全 eureka
文章目录前言1.Docker下载源设置2.Docker下载WordPress3.Docker部署Mysql数据库4.WordPress参数设置5.飞牛云安装Cpolar工具6.固定Cpolar公网地址7.修改WordPress配置文件8.公网域名访问WordPress前言本文主要介绍如何在飞牛云NAS上利用Docker快速搭建并优化WordPress站点的技巧,并且了解了如何借助cpolar实现内
OnionArch:构建高效.NET Core应用的洋葱架构模板
樊慈宜Diane
OnionArch:构建高效.NETCore应用的洋葱架构模板项目地址:https://gitcode.com/gh_mirrors/on/OnionArch项目介绍OnionArch是一个基于.NETCore的演示应用程序,采用了经典的洋葱架构(OnionArchitecture)。洋葱架构是一种分层架构模式,通过将核心业务逻辑与外部依赖(如数据库、UI等)分离,使得应用程序更加模块化、可维护和
[星球大战]阿纳金的背叛
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