当有人这样做时,我正在我们的一台测试服务器上运行跟踪:
我可以在跟踪中捕获的查询之一是:
declare @UserOption int
select @UserOption=convert(int, c.value) from sys.configurations c where c.name='user options'
SELECT
CAST(@UserOption & 1 AS bit) AS [DisableDefaultConstraintCheck],
CAST(@UserOption & 2 AS bit) AS [ImplicitTransactions],
CAST(@UserOption & 4 AS bit) AS [CursorCloseOnCommit],
CAST(@UserOption & 8 AS bit) AS [AnsiWarnings],
CAST(@UserOption & 16 AS bit) AS [AnsiPadding],
CAST(@UserOption & 32 AS bit) AS [AnsiNulls],
CAST(@UserOption & 64 AS bit) AS [AbortOnArithmeticErrors],
CAST(@UserOption & 128 AS bit) AS [IgnoreArithmeticErrors],
CAST(@UserOption & 256 AS bit) AS [QuotedIdentifier],
CAST(@UserOption & …
Run Code Online (Sandbox Code Playgroud) sql-server t-sql sql-server-2014 operator bitwise-comparison
基于 WHERE 子句中的按位比较对列进行索引以进行有效查找的最佳方法是什么,例如
SELECT ID, FLAGS, NAME FROM TABLE WHERE FLAGS & 4 = 4
Run Code Online (Sandbox Code Playgroud)
我的环境是SQL Server 2012。
据我了解,此类查询中不会使用 FLAGS 列上的索引。
我知道另一个选择是将 FLAGS 列分解为单独的列,但我想避免这种情况,因为在某些情况下,这意味着 25 个以上的新列,每个列都需要索引组合来支持常见查询。
有没有什么方法可以对单列建立索引以使按位查询更有效?
我尝试按照下面 dudu 的建议使用带有索引的计算列,但是当我在具有聚集索引的表上使用并开始选择列(而不是仅仅选择 count(*) 时,它不再使用该索引新的计算列。
SELECT
*
INTO
MYTABLE
FROM
(
SELECT 'A' COL_A, 'A' COL_B, CAST(129 AS INT) FLAGS UNION
SELECT 'B' COL_A, 'D' COL_B, CAST(129 AS INT) FLAGS UNION
SELECT 'C' COL_A, 'S' COL_B, CAST(129 AS INT) FLAGS UNION
SELECT 'D' COL_A, 'F' COL_B, CAST(129 AS INT) FLAGS UNION
SELECT 'E' …
Run Code Online (Sandbox Code Playgroud) 知道为什么会这样,
CREATE TABLE f AS
SELECT b'000000001' AS a, x'01' AS b;
Run Code Online (Sandbox Code Playgroud)
这将创建两列
`a` varbinary(2) NOT NULL,
`b` varbinary(1) NOT NULL
Run Code Online (Sandbox Code Playgroud)
然而,当我跑步时,
SELECT a=0, b=0, a=b, a<>b FROM f;
+-----+-----+-----+------+
| a=0 | b=0 | a=b | a<>b |
+-----+-----+-----+------+
| 1 | 1 | 0 | 1 |
+-----+-----+-----+------+
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?从关于BINARY 和 VARBINARY 类型的文档,
所有字节在比较中都很重要,包括
ORDER BY
和DISTINCT
操作。0x00
字节和空格在比较中是不同的,使用0x00 < space
.
这解释了为什么a<>b
,但为什么a=0
,或b=0
那里?
我们正在创建一个新应用程序,其中使用各种表来保存枚举。由于这些表中的 ID 将用于按位比较,我们希望确保插入的新行将自动使用与“设置”的下一位相对应的十进制数。
例如,如果我们有一个闹钟应用程序,我们可能会包含一个“工作日”表,可以按以下方式使用:
CREATE TABLE dbo.Weekdays
(
WeekdayID INT NOT NULL
CONSTRAINT PK_Weekdays PRIMARY KEY CLUSTERED
, WeekdayName VARCHAR(20)
);
INSERT INTO dbo.Weekdays
VALUES (1, 'Sunday')
, (2, 'Monday')
, (4, 'Tuesday')
, (8, 'Wednesday')
, (16, 'Thursday')
, (32, 'Friday')
, (64, 'Saturday');
CREATE TABLE dbo.AlarmsDefined
(
AlarmID INT NOT NULL
CONSTRAINT PK_AlarmsDefined PRIMARY KEY CLUSTERED
, Weekdays INT NOT NULL
);
INSERT INTO dbo.AlarmsDefined (AlarmID, Weekdays)
VALUES (1, 50);
SELECT W.WeekdayName
FROM dbo.AlarmsDefined AD
INNER JOIN dbo.Weekdays …
Run Code Online (Sandbox Code Playgroud)