SQL INDEX 不用于 WHERE ABS(x-y) < k 条件,但用于 y - k < x < y + k 条件

2023-12-03

我有一个查询涉及时差小于 2 小时的几行(~0.08333 天):

SELECT mt1.*, mt2.* FROM mytable mt1, mytable mt2 
                    WHERE ABS(JULIANDAY(mt1.date) - JULIANDAY(mt2.date)) < 0.08333

这个查询相当慢,即 ~ 1 秒(表有 ~ 10k 行)。

一个想法是使用一个INDEX。明显地CREATE INDEX id1 ON mytable(date)没有什么改善,很正常。


然后我注意到神奇的查询CREATE INDEX id2 ON mytable(JULIANDAY(date))

  1. 使用时没有帮助:

    ... WHERE ABS(JULIANDAY(mt1.date) - JULIANDAY(mt2.date)) < 0.08333
    
  2. 使用时没有帮助:

    ... WHERE JULIANDAY(mt2.date) - 0.08333 < JULIANDAY(mt1.date) < JULIANDAY(mt2.date) + 0.08333
    
  3. ...但在使用时极大地提高了性能(查询时间愉快地除以 50!):

    ... WHERE JULIANDAY(mt1.date) < JULIANDAY(mt2.date) + 0.08333
          AND JULIANDAY(mt1.date) > JULIANDAY(mt2.date) - 0.08333
    

当然 1.、2. 和 3. 是等价的,因为在数学上,

|x-y| < 0.08333 <=> y - 0.08333 < x < y + 0.08333
                <=> x < y + 0.08333 AND x > y - 0.08333

问题:为什么解决方案 1. 和 2. 没有使用 INDEX,而解决方案 3. 正在使用它?


Note:

  • 我正在使用 Python + Sqlitesqlite3 module

  • 解决方案 1. 和 2. 没有使用索引这一事实在执行时得到了确认EXPLAIN QUERY PLAN SELECT ...:

    (0, 0, 0, u'SCAN TABLE mytable AS mt1')
    (0, 1, 1, u'SCAN TABLE mytable AS mt2')
    

    事实解决方案 3. 正在使用索引,在执行时显示EXPLAIN QUERY PLAN SELECT ...:

    (0, 0, 1, u'SCAN TABLE mytable AS mt2')
    (0, 1, 0, u'SEARCH TABLE mytable AS mt1 USING INDEX id2 (<expr>>? AND <expr><?)')
    

我相信,包括AND推理如下:

查询中的 WHERE 子句被分解为“术语”,其中每个术语 通过 AND 运算符与其他运算符分隔。如果 WHERE 子句 由 OR 运算符分隔的约束组成,然后整个 子句被认为是 OR 子句所对应的单个“术语” 应用优化。

SQLite 查询优化器概述

可能值得跑步ANALYZE看看情况是否有所改善。

根据评论:

我认为前面添加的段落可以阐明为什么 ABS(x-y) 表达式 ...

添加了以下内容。

为了可供索引使用,术语必须采用以下形式之一:
列=表达式
列 IS 表达式
列 > 表达式
列 >= 表达式
列 列 表达式=列
表达式 > 列
表达式 >= 列
表达式 表达式 列 IN(表达式列表)
列 IN(子查询)
列为空

我不确定它是否适用于BETWEEN (e.g. WHERE column BETWEEN expr1 AND expr2).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL INDEX 不用于 WHERE ABS(x-y) < k 条件,但用于 y - k < x < y + k 条件 的相关文章

  • PHP - SQLite 与 SQLite3

    我已经使用 SQLite 2 8 17 制作了一个 Web 应用程序 我现在才发现有一个 SQLite3 在制作 Web 应用程序时 它以某种方式逃避了我的注意 可能是由于缺少 php 函数的文档 我想知道 使用 SQLite3 比 SQL
  • 当添加列较少时追加到现有 SQLite 表,而不将数据库读入 R

    是否有一些简单的方法 无论是在 SQL 端还是在 R 端 将 data frame 附加到具有更多列的现有表 缺失的列应该用 NA 填充 如果它能够优雅地处理比表 1 列数更多的表 2 那么会加分吗 library RSQLite Crea
  • 在触发器中记录更新操作

    我有一个 UPDATE 触发器 它生成 INSERTED 和 DELETED 表 如下所示 INSERTED Id Name Surname 1 Stack Overflow 2 Luigi Saggese DELETED Id Name
  • Oracle中如何转义单引号? [复制]

    这个问题在这里已经有答案了 我有一列包含某些存储为文本字符串的表达式 其中包括单个引号 例如 错过的交易 包括引号 发生这种情况时如何使用 where 子句 select from table where reason missed tra
  • SQL 解析键值字符串

    我有一个像这样的逗号分隔字符串 key1 value1 key2 value2 key3 value3 key1 value1 1 key2 value2 1 key3 value3 1 我想将它解析成一个如下所示的表 Key1 Key2
  • 如何准备sql语句并绑定参数?

    不幸的是 文档 http www sqlite org完全缺乏示例 这真的很奇怪 就好像它假设所有读者都是优秀的程序员一样 然而 我对C 并且无法真正从文档中弄清楚如何真正准备和执行语句 我喜欢它的实施方式PDO for PHP 通常 我只
  • SQL:两个没有完整列匹配的表的并集

    我有一个table A其中有一组列A1 A2和一个具有一组列的 table bB1 B2 碰巧的是A2 B1但其余列不匹配 也不应该匹配 我想附加表格 所以我使用UNION ALL 对于不匹配的列 我使用null as COLUMN NAM
  • sql查询连接两个服务器中不同数据库的两个表

    我在 ServerS 上的数据库中有两个表 tableA 在 ServerB 上的数据库中有两个表 我只想根据这些表的公共字段名对这些表执行 fullouter join 在 SQL Server 中 您可以创建一个链接服务器 在 Mana
  • 如何确定 SQLite 索引是否唯一? (使用 SQL)

    我想通过 SQL 查询找出索引是否是唯一的 我正在使用 SQLite 3 我尝试了两种方法 SELECT FROM sqlite master WHERE name sqlite autoindex user 1 这将返回有关索引的信息 t
  • 游标与更新

    一家公司使用 SQL Server 数据库来存储有关其客户及其业务交易的信息 您所在的城市引入了新的区号 对于前缀小于 500 的电话号码 区号 111 保持不变 前缀为 500 及以上的号码将分配区号 222 客户表中电话列中的所有电话号
  • 在 SQLite 数据库中存储日期时间值的最佳方式(Delphi)

    我将把日期时间值存储在 SQLite 数据库中 使用 Delphi 和 DISqlite 库 数据库的本质是它永远不需要在计算机或系统之间传输 因此互操作性不是一个限制 相反 我的重点是阅读速度 日期时间字段将被索引 我将对其进行大量搜索
  • 哪种 SQL 模式能够更快地避免插入重复行?

    我知道有两种不重复插入的方法 第一个是使用WHERE NOT EXISTS clause INSERT INTO table name col1 col2 col3 SELECT s s s WHERE NOT EXISTS SELECT
  • Python SQLite SELECT LIKE IN [列表]

    如何在Python中编写SQL查询来选择Python列表中的元素 例如 我有 Python 字符串列表 Names name 1 name 2 name n 和 SQLite table 我的任务是找到最短路线 SELECT element
  • 仅使用 SQL 中的 MAX 函数更新重复行

    我有一张这样的桌子 假设为了举例 NAME是一个唯一的标识符 NAME AGE VALUE Jack Under 65 3 Jack 66 74 5 John 66 74 7 John Over 75 9 Gill 25 35 11 Som
  • 在 Oracle 中创建数据库链接时出错

    我有两个数据库 需要编写跨数据库查询 所以我试图创建一个数据库链接 CREATE PUBLIC DATABASE LINK DBLink CONNECT TO SchemaName IDENTIFIED BY 123 using DBNam
  • 澄清创建临时表的连接顺序

    我在 mysql 中有一个大型查询 涉及将多个表连接在一起 它太慢了 所以我做了 解释 发现它正在创建一个临时表 我怀疑它占用了大部分执行时间 我找到了一些相关资料 mysql 文档 http dev mysql com doc refma
  • 如何将 T-SQL 中的结果连接到列中?

    我正在处理一个查询 它应该给我这样的结果 Name Surname Language Date James Hetfield en gb fr 2011 01 01 Lars Ulrich gb fr ca 2011 01 01 但我的选择
  • 迭代 Sqlite-query 中的行

    我有一个表布局 我想用数据库查询的结果填充它 我使用全选 查询返回四行数据 我使用此代码来填充表行内的 TextView Cursor c null c dh getAlternative2 startManagingCursor c th
  • 出于安全目的,您是否有理由不执行自己的算法来打乱 ID?

    我计划实现我自己的非常简单的 哈希 公式 为具有多个用户的应用程序添加一层安全性 我目前的计划如下 用户创建一个帐户 此时后端会生成一个 ID ID 通过公式运行 假设 ID 57 8926 36 7 或同样随机的东西 然后 我将新的用户
  • 如何重命名 SQL Server 中名称中带有方括号的内容?

    我的一张桌子上有一列 周围有方括号 Book Category 我想重命名为Book Category 我尝试了以下查询 sp rename BookPublisher Book Category Book Category COLUMN

随机推荐

  • 带有空格的图像文件名

    我通过 php 扫描图像文件夹获取图像 URL 数组 某些图像文件名带有空格 空格后面的部分丢失了 例如 这个文件很好 http domain com folder blue sky png 这个文件会丢失sky png部分 http do
  • Django/Python 环境错误?

    当我尝试使用时出现错误syncdb python manage py syncdb 错误信息 File usr local lib python2 6 dist packages django conf init py line 83 in
  • 如何处理我不知道其类型的脚本?

    我的游戏使用各种不同的游戏模式 我想根据所选的游戏模式在场景开始时生成不同的 GameController 脚本 然后其他项目 例如 敌人 将引用主 GameController 无论是 GameController Mode1 GameC
  • Angular Material2 md-select 下拉列表出现在页面底部

    我目前正在 Angular 2 4 0 应用程序中使用 Angular Material2 使用 angular material 2 0 0 beta 1 由于某种原因 md select 下拉列表没有出现在初始值或占位符或箭头上来选择下
  • 无法解析的日期

    我有一个字符串日期 31 Dec 和模式 dd MMM 以及下一个代码 DateFormat formatter new SimpleDateFormat pattern formatter setTimeZone timeZone for
  • VBA 中的 LinEst 函数可以使用数组吗?

    基本上 我不是从单元格中选择一个范围 而是通过使用循环将值存储在数组中 我理想中想做的是将这些数组用作 LinEst 函数中已知的 x 和 y 这样做的目的并不重要 因为我想做的只是我已经编写的代码的一部分 然而 Do 循环 至少是第二个
  • 在 r 中,获取功率曲线中“a”和“b”值的输出值

    我对这个基本问题表示歉意 但无论出于何种原因 我确实陷入困境 我希望从 y a x b 的 a 和 b 功率曲线中获得输出值 假设我有这个数据集 x y log10 x log10 y 7 240 0 84509804 2 38021124
  • 为什么 NSUserDefaults 在我的应用程序和共享扩展程序之间不起作用?

    我有一个带有共享扩展的 iOS 应用程序 我正在尝试使用 NSUserDefaults 和应用程序组在它们之间共享数据 但是 虽然我可以写入 NSUD 对象 读取它 并且synchronize 没有错误 读取扩展名总是会导致nil 我有一个
  • PHP MySQL查询包含关键字/保留字[重复]

    这个问题在这里已经有答案了 我在更新 MySQL 数据 包括 HTML 数据 时遇到了问题 我不断修复错误 然而 一旦修正了一个错误 就会产生另一个错误 目前的错误如下 You have an error in your SQL synta
  • libipopt.so.1:无法打开共享对象文件

    执行基本安装后Ipopt 我能够编译他们提供的示例Ipopt 3 12 5 Ipopt examples hs071 cpp成功使用命令 g hs 071 main cpp hs071 nlp cpp I path to build inc
  • 从 F# 中的二叉搜索树中删除元素

    我正在尝试编写一种方法来从 BST 中删除元素 到目前为止 这就是我所拥有的 我不确定我是否走在正确的轨道上 或者是否有更好的方法通过使用模式匹配来匹配不同的删除情况 即 没有子项 1 个子项 2 个子项 type a bst NL Bin
  • PHP 中的 '(花式撇号?)是什么意思

    我得到了这个示例 PHP 代码 if new value old value 我该怎样称呼这个角色 它有什么作用 如何在键盘上输入它 以及 最重要的是 我可以使用什么来代替人类可读的位置 并且看起来不像我试图炫耀我对晦涩代码速记的知识 我在
  • 在Python中修改文本文件中的每一行

    我有一个大文件 如下例所示 1 10161 10166 3 1 10166 10172 2 1 10172 10182 1 1 10183 10192 1 1 10193 10199 1 1 10212 10248 1 1 10260 10
  • SecurityException:权限被拒绝 ACCESS_ALL_DOWNLOADS

    我正在尝试使用 DownloadManager 下载文件 是的 我知道人们已经遇到了这个错误 但我的似乎没有解决 我每次都尝试过 我已经声明了这个权限
  • 是否可以允许匿名用户仅浏览文件夹中的少数文件

    我想允许匿名用户仅浏览几个文件 例如 default aspx aboutus aspx contactus aspx 等 有没有办法将所有这些文件名写在一个地方 否则我将不得不一次又一次重复下面的代码对于所有文件
  • 高效测地线最近邻

    从纬度 经度数据 以弧度为单位 开始 我尝试有效地找到最近的 n 个邻居 最好是测地线 WGS 84 距离 现在我正在使用sklearn 球树使用半正矢距离 KD Tres 仅采用 minkowskian 距离 这很好而且快速 3 4 秒即
  • 将大文件写入磁盘内存不足异常

    我正在尝试写入然后读取一个大型随机文件来计算磁盘速度 我尝试了多种算法 但在尝试写入 1GB 文件时不断出现输出或内存异常 这是我尝试过的一些 Method 1 byte data new byte 8192 Random rng new
  • jQuery UI 日期选择器可以禁用周六和周日(以及节假日)吗?

    我使用日期选择器来选择约会日期 我已经将日期范围设置为仅下个月 效果很好 我想从可用选项中排除周六和周日 这可以做到吗 如果是这样 怎么办 有的是beforeShowDay选项 它需要为每个日期调用一个函数 如果允许该日期则返回 true
  • 具有机器人框架的多个远程库

    根据 机器人框架 手册中的示例 为了从远程计算机提供关键字 必须实例化RobotRemoteServer带有实现关键字的类的实例 RobotRemoteServer ExampleRemoteLibrary sys argv 1 如果我有多
  • SQL INDEX 不用于 WHERE ABS(x-y) < k 条件,但用于 y - k < x < y + k 条件

    我有一个查询涉及时差小于 2 小时的几行 0 08333 天 SELECT mt1 mt2 FROM mytable mt1 mytable mt2 WHERE ABS JULIANDAY mt1 date JULIANDAY mt2 da