使用 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)。
您还可以做两件事来提高性能:
- 根据您运行的查询(例如
IsDeleted
和DateCreated
),基于位/字符列和其他列创建索引 - 包括在
SELECT
中返回的列在您的索引中,以便查询不必从表中查找记录。
关于sql - 查询 varchar(1) 列与位标志和日期时间比较是否存在性能问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19171029/