——论语三大主流模型的适配情况:HISA的作用位置是每层Transformer的Attention索引阶段,不改变权重,不改变输出格式,对上下游完全透明。 ——中庸洞见一:瓶颈永远在你没注意到的地方当所有人都在优化Attention计算本身(FlashAttention、MLA、GQA……),HISA的团队发现真正的瓶颈其实是Indexer这个"配角"。 老李的问题也一样——GPU不是瓶颈,索引逻辑才是。架构优化的第一步不是加速,而是找对目标。在AI规约编程大行其道、人人都在堆算力的今天,这个教训尤其珍贵。 洞见二:"两段式过滤"是一种通用模式先粗筛再精排,这个模式出现在:搜索引擎(召回→排序)、数据库查询优化器(统计信息裁剪→精确执行)、推荐系统(粗排→精排)。 上下文长度Indexer占比预警线建议动作≤16K<10%正常32K10-25%观察64K>30%立即优化128K+>50%架构重构八、行动号召:别等论文落地,今天就能干的三件事"天下难事,必作于易;天下大事
前言 上篇博客中提到了空间索引的用途和多种数据库对空间索引的支持情况,那么在应用层以下,好学的小伙伴应该会考虑空间索引的实现原理了。 目前空间索引的实现有 R树和其变种GIST树、四叉树、网格索引等。 网格索引不再多提,使用普通的hash表存储地点和风格之间的映射来实现。 今天要介绍的GeoHash算法实现的空间索引,虽然是以B树实现,但我认为它也借用网格索引的一部分思想。 GeoHash 原理 GeoHash 算法的原理说起来是很简单的,如下图: ? 同样的前缀意味着可以使用 B树 索引查找有相同前缀的点作为附近的点,GeoHash 算法便是这些同样的前缀上面做文章。 墨卡托投影 墨卡托投影,是正轴等角圆柱投影。 放上GitHub源码地址:空间索引-GeoHash 数据入库: 将经纬度通过 GeoHash 算法获取到二进制 GeoHash 码,并将其转成十进制作为这个点的 score 存入 Redis 的 sorted
本文将深入探讨索引堆的基本原理、实现步骤,并通过具体的案例代码详细说明索引堆的每一个细节。 一、索引堆的基本概念 索引堆是一种特殊的堆数据结构,它包含两个主要部分: 堆数组:存储堆中的元素。 索引数组:存储堆中元素在堆数组中的位置。 索引堆具有以下特性: 堆序性质:堆中的元素满足最大堆或最小堆的性质。 索引映射:通过索引数组可以快速定位到堆中元素的位置。 二、索引堆的操作 索引堆支持以下主要操作: 插入元素:将新元素添加到堆数组的末尾,并更新索引数组。 删除元素:删除指定索引对应的元素,并调整堆和索引数组。 索引堆的构建 构建索引堆的过程包括: 初始化:将数组中的元素按顺序放入堆数组,并将索引放入索引数组。 构建最大堆:从最后一个非叶子节点开始,向下调整以保持堆序性质。 在实际编程中,索引堆可以用于实现高效的优先队列,例如在图算法、任务调度等领域有着广泛的应用。通过上述实现,你可以根据自己的需求进一步扩展和优化索引堆的功能。
where | +----+-------------+--------+------+---------------+------+---------+------+--------+- 由于不是最左前缀,索引这样的查询显然用不到索引 ,但是如果通配符不是只出现在末尾,则无法使用索引。 (必须是最左前缀),但是范围列后面的列无法用到索引。 同时,索引最多用于一个范围列,因此如果查询条件中有两个范围列则无法全用到索引。 看来MySQL还没有智能到自动优化常量表达式的程度,因此在写查询语句时尽量避免表达式出现在查询中,而是先手工私下代数运算,转换为无表达式的查询语句。
上面的查询从分析结果看用到了PRIMARY索引,但是key_len为4,说明只用到了索引的第一列前缀。 ,因为title未提供,所以查询只用到了索引的第一列,而后面的from_date虽然也在索引中,但是由于title不存在而无法和左前缀连接,因此需要对结果进行扫描过滤from_date(这里由于emp_no 如果想让from_date也使用索引而不是where过滤,可以增加一个辅助索引<emp_no, from_date>,此时上面的查询会使用这个索引。 除此之外,还可以使用一种称之为“隔离列”的优化方法,将emp_no与from_date之间的“坑”填上。 当然,如果title的值很多,用填坑就不合适了,必须建立辅助索引。
MySQL的优化主要分为结构优化(Scheme optimization)和查询优化(Query optimization)。本章讨论的高性能索引策略主要属于结构优化范畴。 最左前缀原理与相关优化 高效使用索引的首要条件是知道什么样的查询会使用到索引,这个问题和B+Tree中的“最左前缀原理”有关,下面通过例子说明最左前缀原理。 这里先说一下联合索引的概念。 在上文中,我们都是假设索引只引用了单个的列,实际上,MySQL中的索引可以以一定顺序引用多个列,这种索引叫做联合索引,一般的,一个联合索引是一个有序元组<a1, a2, …, an>,其中各个元素均为数据表的一列 为了避免多个索引使事情变复杂(MySQL的SQL优化器在多索引时行为比较复杂),这里我们将辅助索引drop掉: ALTER TABLE employees.titles DROP INDEX emp_no 这里有一点需要注意,理论上索引对顺序是敏感的,但是由于MySQL的查询优化器会自动调整where子句的条件顺序以使用适合的索引,例如我们将where中的条件顺序颠倒: EXPLAIN SELECT *
引言 条件中对索引列进行运算导致索引失效是一种常见的性能陷阱。本文深入解读PawSQL的自动优化算法如何针对5种不同的场景,通过智能重写让失效的索引重新生效。 PawSQL优化算法剖析 PawSQL采用了一种逆向思维:既然不能改变索引本身,那就改变查询条件。通过数学等价变换,将作用在索引列上的函数或运算转移到常量一侧,从而让索引重新发挥作用。 实际应用场景举例 用户年龄查询优化 优化前: -- 查询出生年份,YEAR函数导致索引失效 SELECT * FROM users WHERE YEAR(birthday)=1990; 优化后: :从O(n)复杂度降低到O(log n) 执行时间:在大表上可能从几秒降低到毫秒级别 资源消耗:显著减少CPU和I/O开销 结语 PawSQL的这个索引优化算法体现了数据库优化领域的一个重要思想 对于数据库开发者而言,理解这类优化算法的原理,不仅能帮助我们更好地使用工具,也能提升我们的SQL编写技能。毕竟,最好的优化,始终是在编写阶段就考虑到索引的使用。
常见优化方法 联合索引最左前缀原则 复合索引遵守「最左前缀」原则,查询条件中,使用了复合索引前面的字段,索引才会被使用,如果不是按照索引的最左列开始查找,则无法使用索引。 ,这样做不仅可以节省数据库的 CPU,还可以起到查询缓存优化效果。 = 2; 复制代码 可以使用in进行优化: select * from artile where status in (0,3) 复制代码 使用覆盖索引 所谓覆盖索引,是指被查询的列,数据能从索引中取得 如果phone字段是varchar类型,则下面的SQL不能命中索引: select * from user where phone=12345678901; 复制代码 可以优化为: select * from 避免使用or来连接条件 应该尽量避免在 where 子句中使用 or 来连接条件,因为这会导致索引失效而进行全表扫描,虽然新版的MySQL能够命中索引,但查询优化耗费的 CPU比in多。
写在前面 在我们日常使用数据库的时候,肯定避免不了对数据库的优化。那么对数据库的优化又少了不索引的知识。 是的,建立索引能极大地提高查询的效率。 那么你知道吗,如果合理建立索引,可以更大地榨出数据库的性能——也就等同于进一步提高查询效率。 写下这篇文章就是为了记录一下对索引的优化,合理建立索引。 ) where user_name = '我是用户名' and user_phone='110' 此种情况出现的概率比较小,毕竟mysql的解释器很复杂,也做了足够多的优化。 只有排查慢日志并且分析确定索引冲突的情况才需要强制使用索引。 优化 (总结) 只在经常使用的字段上建立索引,否则会拖慢数据更新和插入的速度。 长字符串可以使用前缀索引,只对字符串的前面一定字符长度建立索引。 组合索引的顺序合理优化(会有新文章介绍) 当多个单字段索引发生冲突时,强制使用某个索引。
全文索引(LIKE优化) 优化的方式就是建立全文检索FULLTEXT 使用Mysql全文检索FULLTEXT的先决条件 MyISAM 引擎表和 InnoDB 引擎表(MySQL 5.6 及以上版本)都支持中文全文检索 order by关键字优化 尽量使用index方式排序,避免使用filesort方式。 增大sort_buffer_size参数的设置、增大max_length_for_sort_data参数的设置 group by关键字优化 实质是先排序后进行分组,遵照索引键的最佳左前缀, 当无法使用索引列时 explain显示了MySQL如何使用索引来处理select语句以及连接表。 可以帮助选择更好的索引和写出更优化的查询语句。 Not exists MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了。
什么是索引(What is indexing)? 索引是对记录集的多个字段进行排序的方法。 副作用是索引需要额外的磁盘空间,对于MyISAM引擎而言,这些索引是被统一保存在一张表中的,这个文件将很快到达底层文件系统所能够支持的大小限制,如果很多字段都建立了索引的话。 这就是索引用来改进的地方。 假如索引记录只包含一个索引列以及一个指向原记录数据的指针,那么它显而易见会比原记录(多列)要小。所以索引本身所需要的磁盘块要更少,扫描数目也少。 鉴于创建索引需要额外的磁盘空间(上面的例子需要额外的277778个磁盘块),以及太多的索引会导致文件系统大小限制所产生的问题,所以对哪些字段建立索引,什么情况下使用索引,需要审慎考虑。 低基数的二分查找效率将降低为一个线性排序,而且查询优化器可能会在基数小于记录数某个比例时(如30%)的情况下将避免使用索引而直接查询原表,所以这种情况下的索引浪费了空间。
索引优化 1. 尽量全值匹配 当建立索引后,能再where条件中使用索引列,就尽量使用。 最佳左前缀法则 如果是复合索引,就要遵守最左前缀法则,意思是:查询从最左前列开始,并且不跳过索引中的列。 同样索引列是name,age,pos。 不在索引列上做任何操作 不在索引列上(计算,函数,自动或者手动的进行类型转换),会导致索引失效。 尽量使用覆盖索引 覆盖索引(只访问索引的查询(索引列和查询列一致)),而尽量避免 select * 6. 不等于要慎用 在使用不等于(! EXPLAIN select name,age from staffs where name='July' or name = 'z3' 除了索引优化之外,还有一些查询优化的技巧: 1.
写在前面 在我们日常使用数据库的时候,肯定避免不了对数据库的优化。那么对数据库的优化又少了不索引的知识。 是的,建立索引能极大地提高查询的效率。 那么你知道吗,如果合理建立索引,可以更大地榨出数据库的性能——也就等同于进一步提高查询效率。 写下这篇文章就是为了记录一下对索引的优化,合理建立索引。 ) where user_name = '我是用户名' and user_phone='110' 此种情况出现的概率比较小,毕竟mysql的解释器很复杂,也做了足够多的优化。 只有排查慢日志并且分析确定索引冲突的情况才需要强制使用索引。 优化 (总结) 只在经常使用的字段上建立索引,否则会拖慢数据更新和插入的速度。 长字符串可以使用前缀索引,只对字符串的前面一定字符长度建立索引。 组合索引的顺序合理优化(会有新文章介绍) 当多个单字段索引发生冲突时,强制使用某个索引。
select * from tb1 where email = 999; 普通索引的不等于不会走索引 - != select * from tb1 where email ! = 123 - > select * from tb1 where email > 'alex' 特别的:如果是主键或索引是整数类型,则还是会走索引 select * from by select name from s1 order by email desc; 当根据索引排序时候,select查询的字段如果不是索引,则不走索引 select email 如果组合索引为:(name,email) name and email -- 使用索引 name -- 使用索引 email (经常使用多个条件查询时) - 尽量使用短索引 - 使用连接(JOIN)来代替子查询(Sub-Queries) - 连表时注意条件类型需一致 - 索引散列值(重复少)不适合建索引,例:性别不适合 image.png
覆盖索引 该sql命中了索引,但未覆盖索引。 select * from s1 where id=123; 利用id=123到索引的数据结构中定位到该id在硬盘中的位置,或者说再数据表中的位置。 id,就减去了这份苦恼,如下 这条就是覆盖索引了,命中索引,且从索引的数据结构直接就取到了id在硬盘的地址,速度很快 select id from s1 where id=123; 联合索引 create , d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。 =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器 会帮你优化成索引可以识别的形式 #3.尽量选择区分度高的列作为索引, 索引一定要创建在 where 后的条件列上,而不是 select 后的选择数据的列上,另外,我们要尽量选择在唯一值多的大表上的列建立索引,例如:男女性别列唯一值, 不适合建立索引 慢查询优化 先运行看看是否真的很慢
如果只有分别基于col1 和 col2的单列索引,优化器会尝试使用索引合并优化,或者尝试使用更具筛选性(能够排除更多的无关数据行的)的索引。 多列索引,可以使用任何的前缀索引来进行查询。 MySQL 会使用Turbo Boyer-Moore 字符串查询算法来进行查询。 条件 col_name IS NULL 当col_name 上有索引时会使用索引。 无法使用HASH索引优化ORDER BY 操作。(这种类型的索引无法用于查询排序) MySQL无法通过此索引估计范围条件间的数据行(优化器对于范围查询的优化(选择索引))。 优化器可以针对ref, range, 和index_merge 类型索引访问,松散索引扫描,联合查询和排序优化及MIN()/MAX() 优化使用扩展二级索引。 当优化器没有选择我们希望的索引,那么我们也可以通过其它方式使强制调整优化器选择。
写在前面 在我们日常使用数据库的时候,肯定避免不了对数据库的优化。那么对数据库的优化又少了不索引的知识。 是的,建立索引能极大地提高查询的效率。 那么你知道吗,如果合理建立索引,可以更大地榨出数据库的性能——也就等同于进一步提高查询效率。 写下这篇文章就是为了记录一下对索引的优化,合理建立索引。 ) where user_name = '我是用户名' and user_phone='110' 此种情况出现的概率比较小,毕竟mysql的解释器很复杂,也做了足够多的优化。 只有排查慢日志并且分析确定索引冲突的情况才需要强制使用索引。 优化 (总结) 只在经常使用的字段上建立索引,否则会拖慢数据更新和插入的速度。 长字符串可以使用前缀索引,只对字符串的前面一定字符长度建立索引。 组合索引的顺序合理优化(会有新文章介绍) 当多个单字段索引发生冲突时,强制使用某个索引。
序言 数据库的优化方法有很多种,在应用层来说,主要是基于索引的优化。 ;如果这些结果在查询编译时就能得到,那么就可以被SQL优化器优化,使用索引,避免表扫描,因此将SQL重写如下: select * from record where CardNo like '5378% 因此,我们需要在该字段上建立索引。 第八掌 利用HINT强制指定索引 在ORACLE优化器无法用上合理索引的情况下,利用HINT强制指定索引。 关键字后面,加上“/*+INDEX(表名称,索引名称)*/”的方式,强制ORACLE优化器用上该索引。 另外,值得注意的是:随着时间的推移和数据的累计与变化,ORACLE对SQL语句的执行计划也会改变,比如:基于代价的优化方法,随着数据量的增大,优化器可能错误的不选择索引而采用全表扫描。
---- 利用索引优化锁 为什么索引能优化锁 Innodb采用的行级锁,只有在修改行时才会对需要修改的行加锁。 但是这种情况只有在Innodb层过滤掉不需要的行是才有效。 所以利用索引可以过滤掉不需要的数据, 使用索引的话,仅需要锁定被索引检索出来的数据,而不是锁定全部数据,从而达到优化锁的目的。 索引可以减少锁定的行数 索引可以加快处理速度,同时也加快了锁的释放 ---- 演示 举个例子 (演示锁, 肯定需要两个会话了) 无索引的情况 (获取不同的数据 发生了阻塞) session 1 : mysql 然后把last_name的索引加上去,然后重新做下试验 。 ------》可以看到索引对锁的优化后, 增加了并发,提高DB的性能 当然了,你要是会话二和会话一查询的都是统一批数据,比如都是WOOD,因为会话一未提交, 会话二肯定会被阻塞的。 这里简单提一下。
索引优化常见手段 全值匹配 EXPLAIN SELECT * FROM student WHERE stu_name= '关羽'; 在这里插入图片描述 查看索引长度是74=(3*24+2),可以算出联合索引中只使用了 ,上面的语句应该会使用索引的,但是由于在索引字段上面使用了函数,导致索引失效,mysql在使用优化器的时候,发现索引字段上面使用了函数,将会放弃索引查找,因为它觉得全表扫描会更快。 使用索引覆盖,select 查询的字段包括在索引中 explain select stu_name from student where stu_name like '%备%' 深入索引优化 我们很好奇 order by 总结: 排序字段尽量是索引字段 尽量使用索引覆盖 where字段和排序字段遵循最左前缀 出现filesort ,尽量优化成 using index,在索引中排序肯定比使用文件排序要快得多 文件排序 using filesort 在上面优化中,发现在mysql中排序分为文件排序和索引排序,在无法使用索引排序的情况下,我们就得考虑如何优化文件排序了。