sql - 查询 varchar(1) 列与位标志和日期时间比较是否存在性能问题?

标签 sql sql-server database sql-server-2008

使用 MS SQL 2008,所有表都包含一个 Status varchar(1) 列,指示“I”表示插入的记录,“U”表示更新的记录,“D”表示删除的记录,以及一个 DateCreated 日期时间列和一个DateUpdated 日期时间列。

在大多数情况下,我们只想查询表中的事件记录,我们会这样做:

SELECT column FROM table WHERE Status <> 'D'

为了提供使用情况的透视图,这是最常用的过滤器,因为它几乎出现在每个查询中,并且在连接表时多次出现。

我们正在开发一个新的网络应用程序和数据库,重点是最大限度地提高性能。一个提议是,从这个项目和 future 的项目开始,将 varchar(1) 状态列模式替换为有点像“IsDeleted”,以指示记录是否已删除,并从两个日期时间字段推断更新状态。

换句话说...

SELECT column as InsertedRecords FROM table WHERE Status = 'I' -- Rare case
SELECT column as UpdatedRecords FROM table WHERE Status = 'U' -- Rare case
SELECT column as ActiveRecords FROM table WHERE Status <> 'D'
SELECT column as DeletedRecords FROM table WHERE Status = 'D'

...反而看起来像...

SELECT column as InsertedRecords FROM table WHERE IsDeleted = 0 AND DateCreated = DateUpdated -- Rare case
SELECT column as UpdatedRecords FROM table WHERE IsDeleted = 0 AND DateCreated <> DateUpdated -- Rare case
SELECT column as ActiveRecords FROM table WHERE IsDeleted = 0
SELECT column as DeletedRecords FROM table WHERE IsDeleted = 1

是否有任何切实的性能优势/影响(主要围绕索引和大型查询)或者这两种实现是否完全可以接受?为保持一致性而继续当前模式以使其与之前创建的应用程序/数据库保持一致是否有任何缺点?

最佳答案

我认为仅使用位列而不是 char(1) 列不会有太大损失或 yield 。

就索引而言,仅位列上的索引不会给您带来太多值(value),因为它可能只有 2 个可能的值:1 和 0(我假设您的列不可为空)。

使用 WHERE 的查询条件 DateCreated <> DateUpdated不会很好地工作,因为它无法有效地使用索引,并且很可能表现得比您现有的 char(1) 字段差。

总而言之,我认为您现有的解决方案比位域和日期域更有效。如果您想使用数字,则可以将您的值存储在 tinyint 字段中(例如 I = 0、U = 1、D = 2)。

您还可以做两件事来提高性能:

  • 根据您运行的查询(例如 IsDeletedDateCreated),基于位/字符列和其他列创建索引
  • 包括在 SELECT 中返回的列在您的索引中,以便查询不必从表中查找记录。

关于sql - 查询 varchar(1) 列与位标志和日期时间比较是否存在性能问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19171029/

相关文章:

php - 提前查询。在mysql中对最相关的字段进行排名

Mysql子串查询

java - MSSql 服务器 jpa 空间异常

sql - 在单个 SQL SELECT 语句中区分两行

sql - 一个存储过程怎么可以有多个执行计划呢?

sql - 如何从 SQL Server 中由二进制文字组成的字符串变量设置二进制值?

mysql - 查看整个 MySQL 数据库的所有外键约束

c# - Azure sql 数据库相关异常

java - 在java数据库中使用select语句

java - 如何将连接标记为从 Tomcat 6 中的池中逐出