如何解决MySQL-select 查询很慢,结果很少
我的数据库中有 table1
,其中有 100 万行。
columns: {id,name,timestamp,tag,r,g,b}
indexes: {primary: id,index: timestamp,index: (tag,b)}
每一行都有一个标签(它是一个整数)和一个颜色,由它的组件(r,g,b)保存在单独的列中。我的查询应该是这样的:
SELECT * from table1 WHERE tag=... AND (r>... AND r<... AND g>... AND g<... AND b>... AND b<...) ORDER BY timestamp DESC LIMIT 24;
问题在于,当数据库中只有少数用于选定过滤器(标签和颜色)的记录时,查询速度非常慢(15 秒)。同样值得注意的是,当我从查询中删除 ORDER BY timestamp DESC
时,它运行得非常快,即使有一些结果。如何解决问题,快速查询?
解决方法
我不确定您所说的“很少”是什么意思,但 15 秒似乎很长。
您希望在 (tag,r,g,b)
上为该查询建立索引。
也就是说,这不是最佳索引;或者更准确地说,它是您在 MySQL 中所能获得的最佳状态。您想要的真正索引类型是 RD-Tree,它针对不同维度的范围进行了优化。主要用例是 GIS(地理信息系统)。
但是,我认为 MySQL 不支持 RD-Trees 作为通用索引类型。希望 tag
具有高度选择性并且上述索引能够正常工作。
INDEX(tag,timestamp)
可能会有所帮助。
普遍的问题是优化器看到了两个半有用的索引,但对于选择哪一个没有足够的线索。然后它会选择不太有利的那个。
当您对 g 或 b 的选择相对狭窄时,添加这些可能会有所帮助:
INDEX(tag,g)
INDEX(tag,b)
不幸的是,您在 WHERE
子句中有 4 个“范围”(timestamp,b)并且优化器只能使用一个。我把 tag
放在每个前面(包括你现存的 (tag,b)
,不会超过 r
)。
=
测试应该先进行;索引可以以一个范围结束;索引中将忽略任何后续范围测试(g,b,在您的情况下)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。