索引布尔列与日期时间列的查询性能

2024-01-13

如果索引设置为datetime键入列,而不是boolean输入列(并且查询是在该列上完成的)?

在我当前的设计中,我有两列:

  • is_active小整数(1),indexed
  • deleted_at约会时间

查询是SELECT * FROM table WHERE is_active = 1;

如果我在上面建立索引,会不会慢一些deleted_at列,并运行这样的查询SELECT * FROM table WHERE deleted_at is null; ?


这是具有 10M 行的 MariaDB (10.0.19) 基准(使用序列插件 https://mariadb.com/kb/en/mariadb/sequence/):

drop table if exists test;
CREATE TABLE `test` (
    `id` MEDIUMINT UNSIGNED NOT NULL,
    `is_active` TINYINT UNSIGNED NOT NULL,
    `deleted_at` TIMESTAMP NULL,
    PRIMARY KEY (`id`),
    INDEX `is_active` (`is_active`),
    INDEX `deleted_at` (`deleted_at`)
) ENGINE=InnoDB
    select seq id
        , rand(1)<0.5 as is_active
        , case when rand(1)<0.5 
            then null
            else '2017-03-18' - interval floor(rand(2)*1000000) second
        end as deleted_at
    from seq_1_to_10000000;

来衡量我使用的时间set profiling=1并运行show profile执行查询后。从分析结果中我取值Sending data因为其他所有事情总共都不到一毫秒。

TINYINT index:

SELECT COUNT(*) FROM test WHERE is_active = 1;

运行时间:~738 msec

时间戳 index:

SELECT COUNT(*) FROM test WHERE  deleted_at is null;

运行时间:~748 msec

索引大小:

select database_name, table_name, index_name, stat_value*@@innodb_page_size
from mysql.innodb_index_stats 
where database_name = 'tmp'
  and table_name = 'test'
  and stat_name = 'size'

Result:

database_name | table_name | index_name | stat_value*@@innodb_page_size
-----------------------------------------------------------------------
tmp           | test       | PRIMARY    | 275513344 
tmp           | test       | deleted_at | 170639360 
tmp           | test       | is_active  |  97107968 

请注意,虽然 TIMESTAMP(4 字节)的长度是 TYNYINT(1 字节)的 4 倍,但索引大小甚至还不到两倍。但如果索引大小无法装入内存,则索引大小可能会很大。所以当我改变时innodb_buffer_pool_size from 1G to 50M我得到以下数字:

  • 丁宁:~960 msec
  • 时间戳:~1500毫秒

Update

为了更直接地解决这个问题,我对数据做了一些更改:

  • 我使用 DATETIME 而不是 TIMESTAMP
  • 由于条目通常很少被删除,所以我使用rand(1)<0.99(删除 1%)而不是rand(1)<0.5(删除了 50%)
  • 表大小从 10M 行更改为 1M 行。
  • SELECT COUNT(*)变成SELECT *

索引大小:

index_name | stat_value*@@innodb_page_size
------------------------------------------
PRIMARY    | 25739264
deleted_at | 12075008
is_active  | 11026432

因为 99%deleted_at值为 NULL 时,索引大小没有显着差异,但非空 DATETIME 需要 8 个字节 (MariaDB)。

SELECT * FROM test WHERE is_active = 1;      -- 782 msec
SELECT * FROM test WHERE deleted_at is null; -- 829 msec

删除两个索引后,两个查询都会在大约 350 毫秒内执行。并放弃is_activedeleted_at is null查询在 280 毫秒内执行。

请注意,这仍然不是一个现实的场景。您不太可能希望从 1M 行中选择 990K 行并将其交付给用户。表中可能还会有更多列(可能包括文本)。但它表明,您可能不需要is_active列(如果它不添加附加信息),并且任何索引在最好的情况下对于选择未删除的条目都是无用的。

但是,索引对于选择已删除的行很有用:

SELECT * FROM test WHERE is_active = 0;

有索引时执行时间为 10 毫秒,无索引时执行时间为 170 毫秒。

SELECT * FROM test WHERE deleted_at is not null;

有索引时执行时间为 11 毫秒,无索引时执行时间为 167 毫秒。

丢弃is_active列,有索引时执行时间为 4 毫秒,无索引时执行时间为 150 毫秒。

因此,如果这种情况在某种程度上适合您的数据,那么结论将是:删除is_active列并且不创建索引deleted_at如果您很少选择已删除的条目,请参阅列。或者根据您的需要调整基准并得出自己的结论。

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

索引布尔列与日期时间列的查询性能 的相关文章

  • SQL参数化查询不显示结果

    我的 DataAcess 类中有以下函数 但它没有显示任何结果 我的代码如下 public List
  • 对于双核手机,availableProcessors() 返回 1

    我最近购买了一部 Moto Atrix 2 手机 当我尝试查看手机中的处理器规格时 Runtime getRuntime availableProcessors 返回 1 proc cpuinfo 也仅包含有关处理器 0 的信息 出于好奇
  • MYSQL - 查找最近的前一天

    我可以以某种方式 不使用 PHP 找到一周中最近的前一天日期吗 Like 最近的上一个星期二的日期是哪一天 CURDATE INTERVAL WEEKDAY CURDATE wday IF WEEKDAY CURDATE gt wday 0
  • 根据表sql中的行替换字符串中的字符

    我需要用一些映射的字符替换字符串中的字符列表 我有一个表 dbo CharacterMappings 有 2 列 CharacterToFilter 和 ReplacementCharacter 假设这个表中有3条记录 Filter Rep
  • 连接两个表的查询的 SQL Server“FOR XML”输出

    我是 SQL Server 中 FOR XML 功能的新手 我正在使用 SQL Server 2012 我有两个表 Word 和 Word Expansion 样本数据 表 字 WordOID Word 1 PIPE 2 WIRE 表 Wo
  • 磁盘寻道时间测量方法

    我编写了一个脚本来测量 HDD 上的寻道时间 并且其完成方式的微小变化会导致显着不同的时间 第一个周期在磁盘开头的区域内进行跳转 第二个周期选择磁盘上执行查找的随机区域 相同大小 这种方法显然不同 但我不明白为什么它会改变结果 请注意 对于
  • Hibernate 对集合的查询过滤器

    我想执行以下查询 from Item i where i categoryItems catalogId catId 然而 这会产生以下异常 非法尝试取消引用集合 所以我用谷歌搜索 找到了这个 Hibernate 论坛帖子https for
  • 复选框上的数据绑定

    我目前正在将数据从 SQL 数据库之一提取到我的应用程序中 我可以让它适用于我的文本框和其他项目 但是 我似乎无法让它适用于复选框 这是我正在使用的代码 DataTable dt new DataTable dt using SqlConn
  • 如何将可视选择的文本通过管道传输到 UNIX 命令并将输出附加到 Vim 中的当前缓冲区

    使用 Vim 我尝试将在可视模式下选择的文本通过管道传输到 UNIX 命令 并将输出附加到当前文件的末尾 例如 假设我们有一个 SQL 命令 例如 SELECT FROM mytable 我想做如下的事情
  • 在Python列表中交换元素的最快方法

    在Python中交换两个列表元素是否有比 L a L b L b L a 或者我必须求助于Cython http cython org or Weave http www scipy org Weave或类似的 看起来 Python 编译器
  • 如何在使用连接池时强制 SqlConnection 物理关闭?

    我明白 如果我实例化一个 SqlConnection 对象 我实际上是从连接池中获取一个连接 当我调用 Open 时 它将打开连接 如果我对该 SqlConnection 对象调用 Close 或 Dispose 方法 它将返回到连接池 但
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • 使用 JSON 参数的 Postgres 批量 INSERT 函数

    这是一个plpgsqlpostgres 的函数9 6 它试图INSERT一行 如果插入没有失败 由于违反键约束 那么它会运行更多命令 CREATE FUNCTION foo int text text RETURNS void AS BEG
  • Mysql 中 UNION 子句的替代方案

    我有两张桌子 表 a 表 b table a ID 1 2 3 4 5 7 table b ID 2 3 4 5 6 我必须得到这样的输出而无需UNION命令 ID 1 2 3 4 5 6 7 注意 我有一个联合解决方案 select fr
  • 在sqlite SQL语句中与order by子句结合使用limit

    下面的两条 SQL 语句总是会产生相同的结果集吗 1 SELECT FROM MyTable where Status 0 order by StartTime asc limit 10 2 SELECT FROM SELECT FROM
  • 是否有适用于所有数据库的标准sql

    如下所示 不同数据库的语法有所不同 是否存在适用于所有数据库的标准方法 有没有什么工具可以将任意sql转换为任意sql SQL Server 2005 CREATE TABLE Table01 Field01 int primary key
  • 在 nHibernate 关系中使用实体的 Lite 版本?

    在某些情况下 出于性能原因 创建一个实体的轻量级版本 指向同一个表 但映射的列较少 这是一个好主意吗 例如 如果我有一个包含 50 列的联系人表 并且在一些相关实体中 我可能对 FirstName 和 LastName 属性感兴趣 那么创建
  • 在 MySQL 中使用 COUNT 时如何返回 0 而不是 null

    我使用此查询返回存储在 sTable 中的歌曲列表以及存储在 sTable2 中的总项目数 SQL queries Get data to display sQuery SELECT SQL CALC FOUND ROWS str repl
  • 用于选择特定 div 中具有特定类的锚元素的 jQuery 选择器是什么

    我有一些这样的代码 我想选择每个 a 带有类的标签status在 div 中foo div a class status a div 你可以这样做 foo find status a
  • MySQL 查询计算上个月

    我想计算上个月的订单总额 我收到了从当前日期获取当月数据的查询 SELECT SUM goods total AS Total Amount FROM orders WHERE order placed date gt date sub c

随机推荐

  • 是否可以将参数传递给 Perl 模块加载?

    我目前正在开发一个多环境 perl 脚本 众所周知 如果做得不好 环境配置杂耍可能会非常痛苦 由于我的 Perl 脚本必须允许某些命令行参数用于配置值重载 因此我采用了以下解决方案 package Cfg use strict use wa
  • 如何在具有百分比高度的 div 中间垂直对齐文本? [复制]

    这个问题在这里已经有答案了 这是我现在所拥有的 在其他div中使用vertical align middle并设置line height与相同的值height属性它应该可以工作 唯一的事情是在这些 div 中我使用像素尺寸而不是百分比 谁能
  • 如何向多行文本框添加一行?

    我怎样才能添加一行文本到多线 http msdn microsoft com en us library system windows forms textboxbase multiline 28v VS 80 29 aspx TextBo
  • Solr:使用 EdgeNGramFilterFactory 进行精确短语查询

    在 Solr 3 3 中 是否可以通过EdgeNGramFilterFactory并且对短语查询也敏感 例如 我正在寻找一个字段 如果包含 contrat informatique 则在用户键入以下内容时将找到该字段 contrat 信息学
  • 情节大小固定在闪亮?调整大小不起作用

    我尝试改装this https plot ly r shinyapp plotly events 适合我的目的的闪亮应用程序 由于我想在其上方添加一些文本 因此我使用 Rmd 格式 以下代码与链接中的代码完全相同 只是我删除了服务器和用户界
  • 如何根据包含特定值的行(在任何列中)过滤数据框

    我需要限制数据集 以便它仅返回包含特定字符串的行 但是 该字符串可以存在于许多 8 列中 我怎样才能做到这一点 我见过 str isin 方法 但它返回单行的单个系列 如何删除任何列中包含该字符串的任何行 示例代码 如果我有由生成的数据框
  • UITableView - 辞去外部触摸的第一响应者

    我有一个 UITableView 和一个关联的 UITableViewController 但是 我已经修改了该表 使其也有一个带有文本字段子视图的视图 与往常一样 我希望当用户点击 完成 简单 以及触摸屏幕上除文本字段之外的其他任何位置时
  • 使用变量作为索引来回显批处理文件数组?

    如果我有一个批处理文件 并且我正在设置带有变量索引的数组 echo off SET x 1 SET myVar x happy 我该如何回应才能获得 快乐 我试过了 ECHO myVar x ECHO myVar x ECHO myVar
  • Java 9 + maven + junit:测试代码是否需要自己的 module-info.java 以及将其放在哪里?

    假设我有一个使用 Maven 3 和 junit 的 Java 项目 有src main java and src test java分别包含主要源和测试源的目录 一切都是标准的 现在我想将项目迁移到Java 9 src main java
  • 为什么 python 切片语法不从负索引环绕到正索引?

    我注意到 鉴于l 1 2 3 that l 1 回报 3 正如预期的那样 但是l 1 0 回报 与我的预期非常不同 然后我尝试了 1 1 我期望返回 3 1 但它也会返回 切片语法不从负索引环绕到正索引 反之亦然 是否有充分的理由 看起来它
  • SonarQube/SonarLint/Visual Studio:对解决方案中的所有项目使用一个规则集

    我们目前正在评估 SonarQube SonarLint 在我们的 NET 应用程序中的使用情况 我们对迄今为止所看到的情况非常满意 顺便说一句 值得称赞的是 SonarQube 已经走到了这一步 几年前我在我的博士项目中使用了它 从那时起
  • 如何使用 OleDb 读取 Oracle 中的 CLOB 列?

    我在 Oracle 10g 数据库上创建了一个具有以下结构的表 create table myTable id number 32 0 primary key myData clob 我可以毫无问题地在表中插入行 但是当我尝试使用 OleD
  • 如何以及何时使用 PreventDefault()?

    由此tutorial http blog nmsdvid com when to use return false and when preventdefault 据说 preventDefault 做一件事 停止浏览器默认设置 行为 我在
  • SharedObject 支持哪些数据类型?

    我知道用 SharedObject 存储字符串和数字是一件简单的事情 而且我也熟悉这类事情 var sharedObject SharedObject SharedObject getLocal userData var obj Objec
  • http://localhost/undefined 404(未找到)

    我的问题描述不清楚 让我再尝试一次 注意 这是我的生产 登台和开发网站 不仅仅是评论者似乎认为的那样只是我的开发网站 常见的问题 注意 使用 Chrome 时会出现此问题 而使用 Firefox 时不会出现此问题 问题出现在网站首页 htt
  • 将变量传递到 Zend Form

    我有一个实例化的 zend 表单 form Form Example 现在我想将 ID 从我的控制器传递到我的表单 所以我这样做了 form Form Example array id gt id 在表单内我尝试通过以下方式调用它 this
  • Android 表格布局中的右对齐列

    我想绘制一个表格 其中最后一列应位于表格的最右侧 表格行如下所示 Admin 2 New Network 2 New 事情应该是这样的 Admin 2 New Network 2 New XML
  • “未绑定到有效相机”CameraX 错误

    我试图遵循谷歌的 CameraX入门 代码实验室 我尝试用Java而不是Kotlin来完成它 但是当我运行它并尝试拍照时 它给了我一个错误 说未绑定到有效的相机 我在代码中找不到错误所在 我检查了 logcat 它说表面可能存在问题 它可能
  • 检测实际的形式变化?

    是否有一种现成的方法 也许在一个框架中 来检测表单是否具有changed与其原始值相比 onchange 事件不会执行 因为无论实际更改如何 它都会触发 例如 我可以使用两个 onchange 事件勾选一个复选框 然后再次关闭 最后的手段是
  • 索引布尔列与日期时间列的查询性能

    如果索引设置为datetime键入列 而不是boolean输入列 并且查询是在该列上完成的 在我当前的设计中 我有两列 is active小整数 1 indexed deleted at约会时间 查询是SELECT FROM table W