开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到2群(共800人左右 1 + 2 + 3)新人会进入3群,回复有特殊需求的会同时进2群和3群。
基于半瓶子咣当的状态,PG, MYSQL , POLARDB , MONGODB ,REDIS 还是都能舞刀弄枪几下的,但是这个弄这弄着,这记忆力就会不好,因为我一直对于MYSQL 8 的优化器的进步,表达了一个满意的记忆,虽然你比不了,oracle, sql server ,pg ,但是MYSQL 也差不太多了,实际上教育了我,版本MYSQL 8.013(生产) 试验 8.030 实际上这二者在这个问题上没有差别。当然也再次印证了, 开源数据库一定在某些方面是给你一个 disabled 的 状态,否则怎么就商业数据库卖钱呢,不同意的参见,今天一起发的 POSTGRESQL EDB 公司的文章, PG ,MYSQL 同时都能印证,不花钱的产品,你要求别太高。
废话太多,在生产上的一个表字段中包含了连续了 A + B + C A 为字符,B 为字符,C为日期,索引中也是这样建立的,A B C ,但是在查询中出现了 A + C (C为范围查询),虽然实际上走了我们建立的索引,但是实际上,和没走也差不多。下面用一个实例来反馈
测试数据100万
select * from test_innodb where user_id = '00OSL5Whq664QQzaYbOp' and create_time >= '2023-04-14 10:00:00' and create_time < '2023-04-19 10:00:00';
语句很简单,另外数据中在生产系统中,user_id 的位置并不是唯一值,而测试系统中是唯一值,group_id 不是唯一值,并且里面有NULL ,时间就是我们的时间,没有空值。
索引我们先建立三个字段的,然后执行了查询语句。从图中看,我们可以看到走了三个字段的联合索引,但是基本上在选择字段部分仅仅是使用 user_id 作为实际索引使用的部分。
在我们创建了仅仅有 user_id 和 create_time 的索引,我们再次运行语句,可以看到整体的执行的中的执行计划,是走了索引的全部
我的问题就来了,这个为什么同样的数据库同样的语句,同样的MYSQL,执行计划中,仅仅是一个索引,中间多个一个字段,就忽略了后面的日期范围部分,WHY ,我的记忆是MYSQL 是可以跳过索引中间有字段但是查询里面没有需求的字段。
原因是为什么在 MySQL 中,当使用复合索引(包含多个字段的索引)时,如果中间字段的值为 NULL,那么将仅会走前缀。也就是说,复合索引只有在所有前面字段的值都非 NULL 时,才能被用来检索。
例如,假设我们有一个包含三个字段(a, b, c)的复合索引:
CREATE INDEX idx_example ON table_name (a, b, c);
以下查询可以使用复合索引 idx_example
:
SELECT * FROM table_name WHERE a = 1 AND b = 2;
但是,如果字段 b
的值为 NULL,那么复合索引将只能走前缀,即只会用到字段 a
:
SELECT * FROM table_name WHERE a = 1 AND b IS NULL;
此时,索引将不再涉及字段 c
,因为字段 b
的值为 NULL,导致索引只能走前缀。
那么别的数据库是否也有这个问题,我们来看看 MYSQL 的死对头 POSTGRESQL
在 PostgreSQL 中,当使用复合索引(包含多个字段的索引)时,即使中间字段的值为 NULL,该复合索引仍可以用于查询。这是因为 PostgreSQL 对 NULL 值进行了特殊处理,将其包含在索引内。这种行为与 MySQL 不同。
例如,假设我们有一个包含三个字段(a, b, c)的复合索引:
CREATE INDEX idx_example ON table_name (a, b, c);
以下查询可以使用复合索引 idx_example:
SELECT * FROM table_name WHERE a = 1 AND b = 2;
同时,当字段 b 的值为 NULL 时,PostgreSQL 也能够使用该复合索引:
SELECT * FROM table_name WHERE a = 1 AND b IS NULL;
在这个例子中,即使 b 字段的值为 NULL,索引依然可以被用来检索。
那么到此为止,同为免费数据库的POSTGRESQL 是可以在这样的情况来使用索引的,那么我们就会引发一个MYSQL 性能差另一个问题
在查询中,MYSQL 可能会由于应付上面的查询,需要建立更多的索引来满足查询的性能要求,而其他的数据库则不需要,一个索引基本上可以搞定。
最终导致MYSQL 的查询,插入,删除等性能都相对于其他的数据库低下。好吧,不能说下去,MYSQL的FUNS 已经举着刀杀来了。