当前位置: 首页 > 面试题库 >

如何优化SQLite ORDER BY rowid?

黎震博
2023-03-14
问题内容

我想查询我的sqlite数据库中所有大于20的“级别”值,将结果限制为100,并按rowid进行排序。

当按rowid排序时,查询要慢得多。该数据库包含约300万条记录,级别的最大值为50。将为级别创建一个索引。

该语句大约需要20毫秒:

SELECT * FROM log WHERE level > 20 LIMIT 100

该语句大约需要100毫秒:

SELECT * FROM log WHERE level > 20 ORDER BY rowid LIMIT 100

该语句大约需要1000毫秒(不存在级别值大于50的行):

SELECT * FROM log WHERE level > 50 ORDER BY rowid LIMIT 100

有没有一种方法可以对此进行优化,以实现更快的ORDER BY查询?

这是使用的索引:

CREATE INDEX level_idx ON table (level)

问题答案:

有两种可能的方法来执行此查询:

  1. level>20level_idx索引中搜索第一个条目,然后扫描所有随后的条目并从表中获取每个对应的行。由于索引条目未按rowid顺序存储,因此必须对所有结果进行排序。然后可以返回其中的前100个。

  2. 忽略索引。扫描表的所有行(已按rowid顺序存储),并返回与level列匹配的任何行。

数据库估计第二种方法更快。

如果您估计第一种方法更快,即与level筛选器匹配的行数太少,以至于对剩余的行进行获取和排序比在扫描表时忽略不匹配的行要快,那么您可以强制数据库使用带有INDEXED
BY子句的索引:

SELECT *
FROM log INDEXED BY level_idx
WHERE level > 20
ORDER BY rowid
LIMIT 100

但是,如果您自己的估计是错误的,则强制索引可能会导致可怕的速度下降。



 类似资料:
  • 如何清理linux不需要的软件包

  • 我想知道如何优化我的画圆方法。在将顶点发送到opengl之前,我寻求如何尽快生成顶点。 FillRect函数只绘制一个四边形,因此DrawCircle函数绘制100个四边形,这些四边形按cos、sin和半径移动。 我怎么能以不同的方式画圆呢?

  • 有时候你会遇到循环,或者递归函数,它们会花费很长的执行时间,可能是你的产品的瓶颈。在你尝试使循环变得快一点之前,花几分钟考虑是否有可能把它整个移除掉,有没有一个不同的算法?你可以在计算时做一些其他的事情吗?如果你不能找到一个方法去绕开它,你可以优化这个循环了。这是很简单的,move stuff out。最后,这不仅需要智慧而且需要理解每一种语句和表达式的开销。这里是一些建议: 删除浮点运算操作。

  • 这样一堆 if 合理吗?后面还会加判断,会更多。 再拆分的话感觉不太好,有更好的方法吗?

  • 本文向大家介绍js如何性能优化?相关面试题,主要包含被问及js如何性能优化?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 减少HTTP请求 使用内容发布网络(CDN) 添加本地缓存 压缩资源文件 将CSS样式表放在顶部,把javascript放在底部(浏览器的运行机制决定) 避免使用CSS表达式 减少DNS查询 使用外部javascript和CSS 避免重定向 图片lazyLoad  

  • 本文向大家介绍MySQL如何优化索引,包括了MySQL如何优化索引的使用技巧和注意事项,需要的朋友参考一下 1.  MySQL如何使用索引 索引用于快速查找具有特定列值的行。如果没有索引,MySQL必须从第一行开始,然后遍历整个表以找到相关的行。表越大,花费越多。如果表中有相关列的索引,MySQL可以快速确定要在数据文件中间查找的位置,而不必查看所有数据。这比顺序读取每一行要快得多。 大多数MyS

  • 本文向大家介绍如何进行SQL优化?相关面试题,主要包含被问及如何进行SQL优化?时的应答技巧和注意事项,需要的朋友参考一下 (1)选择正确的存储引擎 MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算

  • 关于spring缓存的问题: 类似我通过注解方式定义的缓存,我定义了设置缓存,获取缓存、删除缓存三个方法,但我感觉其中设置、删除缓存方法都很奇怪,设置缓存居然要提供返回值才能实际设置;删除缓存又是一个空的方法体。缓存是通过这种方式使用的吗?我感觉很奇怪 我在 application.yml 中配置了缓存的 cache-names;然后使用 @Cachable 注解IDE还是会提示要提供 name,