本机真实往一个UNIQUE列里连续插入3个NULL,全部真实成功;紧接着插入两个真实相同的非NULL值,第二次真实立刻报错——同一个唯一索引,对NULL和非NULL值真实是两套判断标准。
本机真实用A锁住队列表的前2行不提交,B用SKIP LOCKED真实0.0002秒就拿到了后2行(跳过被锁的),C用普通FOR UPDATE真实被阻塞了整整1秒,直到A提交才拿到跟A一样的前2行。
本机真实跑5条id分别是1到5的SELECT,真实用performance_schema.events_statements_summary_by_digest查询,验证这5条字面量不同的语句真实被归到了同一个digest下,COUNT_STAR=5,字面量真实被替换成了问号。
本机真实查SHOW BINARY LOG STATUS,看到GTID集合efd7431a-...:1-143,真实执行一条INSERT后GTID立刻变成1-144;再用SHOW BINLOG EVENTS真实看到ROW格式下一条批量插入真实拆成了多个Write_rows事件。
本机真实测innodb_flush_log_at_trx_commit三种取值下2000次单行事务提交的耗时:1(每次提交真实刷盘+fsync)真实耗时0.2514秒,2(每次刷盘不fsync)真实0.1571秒,0(都不做)真实0.1758秒——最安全的选项真实也最慢。
本机真实用A开一个事务只做了一次普通SELECT不提交,B的ALTER TABLE真实被阻塞1.5099秒;更关键的是C在ALTER已经排队之后才发起的普通SELECT,真实也被卡住了1.0074秒——不是插队跳过ALTER,而是真实排在它后面一起等。
本机真实对同一条查询分别跑EXPLAIN和EXPLAIN ANALYZE,前者估算rows=98851,后者真实执行后actual显示rows=189960——估算值只有真实值的52%,直接复用了本系列此前发现的优化器统计偏差场景,用EXPLAIN ANALYZE真实把这个偏差量化了出来。
本机真实插入10万行active后EXPLAIN估算49999行,再真实插入40万行banned(没执行ANALYZE),估算真实变成249999——跟真实的400000相差近40%;执行ANALYZE TABLE之后估算只是从249999微调到249747,几乎没有真实变化,因为统计信息本来就是抽样的,不是精确计数。
本机真实查mysql.innodb_table_stats和innodb_index_stats,看到真实的n_rows、n_diff_pfx01、sample_size=20等具体数字;再建一张STATS_PERSISTENT=0的表,即使执行了ANALYZE TABLE,它真实完全不会出现在这两张持久化统计表里——统计信息真实只存在于内存中。
本机真实用ANALYZE TABLE UPDATE HISTOGRAM在无索引列上建直方图,把行数估算从固定的20000真实修正到接近准确的188774——但真实发现一个坑:在从没跑过普通ANALYZE TABLE的新表上单独跑UPDATE HISTOGRAM,估算反而真实崩到27.5这种离谱的错误值。
本机真实建一张30万行、两个独立单列索引的表,OR条件真实触发Deduplicate(Index Merge Union),AND条件真实触发Intersect(Index Merge Intersection),真实测出Index Merge比强制全表扫描快约30倍(1.5ms vs 46ms)。
本机真实用EXPLAIN FORMAT=JSON确认了multi_range_read:true真实生效,但真实测出的耗时却反直觉:mrr=on反而比mrr=off略慢(多次重复测都是如此)——在本机NVMe SSD上,MRR为了排序访问顺序付出的开销,真实没有换来预期的收益。