主要观点:圣诞节期间工作相对安静,分享一个关于一张表和一个索引导致错误的故事。
关键信息:用户反映某查询性能不一致,有时 3 分钟,有时 30 分钟甚至不结束。实际问题是原查询在有几亿行的表中仅返回千余行却需数分钟,原查询基于带自连接的视图,简化后发现是一个表的查询超慢,索引看似完美但因每行都要验证小时和分钟导致慢,计划扫描行数约 3000 万后筛选剩 1000 多,尝试创建额外部分索引或把小时、分钟加入索引均无效,因extract
等不可用于索引,后发现仅统计行数时运行毫秒,是因为采用了INDEX ONLY SCAN
,通过改写查询让原查询也能以同样方式优化。
重要细节:原查询语句为SELECT * FROM large_table WHERE col1='AAA' AND col2='BCD' AND created_at BETWEEN '01-01-2012' AND '12-31-2012' AND extract (hour FROM created_at)=16 AND extract (minute FROM created_at)=15
,有相应索引CREATE INDEX large_table_index ON large_table (col1, col2, created_at)
,改写后的查询语句为SELECT * FROM large_table WHERE (col1, col2, created_at) IN (SELECT col1, col2, created_at FROM large_table WHERE col1='AAA' AND col2='BCD' AND created_at BETWEEN '01-01-2012' AND '12-31-2012' AND extract (hour FROM created_at)=16 AND extract (minute FROM created_at)=15)
。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。