sqllite查询数据量_详解SQLite中的查询规划器

1.0 介绍

查询规划器的任务是找到最好的算法或者说“查询计划”来完成一条SQL语句。早在SQLite 3.8.0版本,查询规划器的组成部分已经被重写使它可以运行更快并且生成更好的查询计划。这种重写被称作“下一代查询规划器”或者“NGQP”。

这篇文章重新概括了查询规划的重要性,提出来一些查询规划固有的问题,并且概括了NGQP是如何解决这些问题。

我们知道的是,NGQP(下一代查询规划器)几乎总是比旧版本的查询规划器好。然而,也许有的应用程序在旧版本的查询规划器中已经不知不觉依赖了一些不确定或者不是很好的特性,这时候将查询规划器更新升级到NGQP,这些应用程序可能会导致程序闪退现象。NGQP必须考虑这种风险,提供一系列的检查项来减小风险和解决可能会引起的问题。

在NGOP上关注此文档。对于更一般的sqlite查询规划器以及涵盖sqlite整个历史的概述,请参阅:“sqlite查询优化程序概述”。

2.0 背景

对于用简单的几个指数对单个表的查询,通常会有一个明显的最佳的算法选择。但是对于更大更复杂的查询,诸如众多指数与子查询的多路连接,对于计算结果,可能有数百,数千或者数百万的合理算法。如此查询规划的工作是选择一个单一的“最好”的有众多可能性的查询计划。

查询规划器是什么使得SQL数据库引擎变得如此惊人的有用与强大。(这是真正的所有的sql数据库引擎,不只是sqlite。)查询规划器使得编程人员从苦差事中选择一个特定的查询计划之中释放出来。从而允许程序员在更高级别的应用问题里和向最终端用户提供更多的价值之上可以关注更多的心理能量。对于简单的查询,查询计划的选择是显而易见的,虽然是方便的,但并不是很重要的。但是作为应用程序,架构与查询将会变得越来越复杂化。一个聪明的查询规划可以大大地加速和简化应用程序开发的工作。它告诉数据库引擎有什么内容需求是有着惊人的力量的,然后,让数据库引擎找出最好的办法检索那些内容。

写一个好的查询规划器是艺术多于科学。查询规划器必须要有不完整的信息。它不能决定将多久采取任何特别的计划,而实际上无需运行此计划。因此,当比较两个或多个计划时,找出哪些是“最好的”,查询规划器会做出一些假设和猜测,那些假设和猜测有时候会出错。一个好的查询计划要求能找到正确的解决方案,而这些问题是程序员很少考虑的。

2.1 sqlite之中的查询规划器

sqlite的计算使用嵌套循环联接,一个循环中每个标的连接(额外的循环可能会在WHERE句子中插入IN和OR运算符。sqlite认为那些考虑太多啦,但为了简单起见,我们可以在这篇文章之中可以忽略它。)在每次循环时,一个或者更多的指数被使用,并被加速搜索,或者一个循环可能是“全表扫描”读取表中每一行。因此,查询规划分解成两个子任务:

采摘的各种循环的嵌套顺序。

选择每个循环的良好指数。

采摘嵌套顺序一般是更具挑战性地问题。

一旦建立连接的嵌套顺序,每个循环指数的选择通常是显而易见的。

2.2 SQLite查询规划器稳定性保证

对于给出的任何SQL语句,SQLite 通常情况下会选择相同的查询规划假如:

数据库的schema没有明显的改变,例如添加或删除索引(indices),

ANALYZE命令没有返回

SQLite在编译时没有使用SQLITE_ENABLE_STAT3或者SQLITE_ENABLE_STAT4,并且

使用相同版本的SQLite

SQLite的稳定性保证意味着你在测试中高效的运行查询操作,并且你的应用没有更改schema,那么SQLite不会突然选择开始使用一个不同的查询规划,那样有可能在你把你的应用发布给用户之后造成性能问题。如果在实验室里你的应用是工作的,那它在部署之后同样可以工作。

企业级的客户端/服务器SQL数据库通常不能做这样的保证。在客户端/服务器SQL数据库引擎里,服务器跟踪统计表的大小和索引(indices)的数量,查询规划器根据这些统计信息选择最优的规划。一旦在数据库的内容通过增删改改变,统计信息的改变有可能引起对于某些特定的查询,查询规划器使用不同的查询规划。通常新的规划对于更改过的数据结构来说更好。但有时新的查询规划会导致性能的下降。在使用客户端/服务器数据库引擎时,通常会有一个数据库管理员(DBA)来处理这些罕见的问题。但是DBA们不能在像SQLite这样的嵌入式数据库中修复该问题,所以SQLite需要小心的确保查询规划在部署之后不会被意外的改变。

SQLite稳定性保证适用于传统的查询规划和NGQP。

需要注意的很重要的一点是SQLite版本的改变可能引起查询规划的改变。同版本的SQLite通常会选择相同的查询规划,但是如果你把你的应用重新连接到了不同版本的SQLite上,那么查询规划可能会改变。在很罕见的情况下,SQLite版本的改变会引起性能衰减。这是一个你应该考虑把你的应用静态的连接到SQLite而不是使用一个系统范围(system-wide)的SQLite共享库的原因,因为它有可能在你不知情或者不能控制的情况下改变。

3.0 一个棘手的情况

"TPC-H Q8"是一个来自于Transaction Processing Performance Council的测试查询。查询规划器在3.7.17以及之前版本的SQLite中没有为TPC-H Q8选择一个好的规划。并且被认定再怎么调整传统查询规划器也不能修复这个问题。为了给TPC-H Q8查询寻找一个好的好的解决方案,并且能够持续的改进SQLite查询规划器的质量,我们有必要重新设计查询规划器。这个部分将解释为什么重新设计是有必要的,NGQP有什么不同和设法解决TPC-H Q8问题。

3.1 查询细节

TPC-H Q8 是一个8路的join。基于以上所看到的&

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值