Arc*_*ano 1 performance index sql-server
在索引 VARCHAR 列是个好主意/方法吗?这个概念是使用 VARCHAR 作为列。
我想知道,如果我们将SHA-1
散列或SHA-256
散列(如果我是偏执狂)存储为BINARY(20)
列和该列上的索引。
SHA-1
在应用程序端对短字符串执行计算足够快,我们只是通过 SHA 值进行查询。
可能我认为 的长度VARCHAR
会在 10 到 30 个字符左右徘徊,有些会更长但概率较低。
这个问题有 [Performance] 标签,所以我怀疑您可能正在考虑哈希索引。在 SQL Server 中,非聚集索引的最大键长度为1700 字节。无法创建以长字符串列作为键列的非聚集索引。例如,对于下表:
DROP TABLE IF EXISTS #HASH_INDEX_DEMO;
CREATE TABLE #HASH_INDEX_DEMO (
ID BIGINT NOT NULL,
BIG_COLUMN_FOR_U VARCHAR(8000) NOT NULL,
SMALL_COLUMN VARCHAR(10) NOT NULL
);
INSERT INTO #HASH_INDEX_DEMO WITH (TABLOCK)
SELECT RN, REPLICATE(CHAR(65 + RN % 26), (RN % 43) * (RN % 119)), 'SMALL'
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
) q;
Run Code Online (Sandbox Code Playgroud)
尝试创建此索引:
CREATE INDEX I ON #HASH_INDEX_DEMO (BIG_COLUMN_FOR_U);
Run Code Online (Sandbox Code Playgroud)
失败并出现此错误:
消息 1946,级别 16,状态 3,第 19 行操作失败。索引“I”的长度为 1701 字节的索引条目超过了非聚集索引的最大长度 1700 字节。
如果您需要对该列进行相等搜索,则查询优化器必须进行表扫描。例如,以下查询在我的机器上大约需要 0.6 秒:
SELECT ID, SMALL_COLUMN
FROM #HASH_INDEX_DEMO
WHERE BIG_COLUMN_FOR_U = 'A'
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
一种替代方法是在列上创建散列索引并对散列索引和列本身执行相等搜索。CHECKSUM()
可能是最好的选择,因为您不需要任何加密安全性,并且可以接受少量冲突。你主要想要一些小而快的东西。下面的代码添加一个计算列并在该列上创建一个索引:
ALTER TABLE #HASH_INDEX_DEMO ADD BIG_COLUMN_FOR_U_CHECKSUM AS CHECKSUM(BIG_COLUMN_FOR_U);
CREATE INDEX I ON #HASH_INDEX_DEMO (BIG_COLUMN_FOR_U_CHECKSUM);
Run Code Online (Sandbox Code Playgroud)
下面的查询返回与初始查询相同的结果,但 SQL Server 能够使用索引。它在我的机器上在 0.01 秒内完成。
SELECT ID, SMALL_COLUMN
FROM #HASH_INDEX_DEMO
WHERE BIG_COLUMN_FOR_U_CHECKSUM = CHECKSUM('A') AND BIG_COLUMN_FOR_U = 'A'
OPTION (MAXDOP 1);
Run Code Online (Sandbox Code Playgroud)
当密钥长度太长以致于无法使用非聚集索引或磁盘空间非常宝贵时,散列索引是一个不错的选择。在您的问题中,您估计列的长度约为 10 到 30 个字符,增加的复杂性对于您的方案来说可能不值得。
归档时间: |
|
查看次数: |
1408 次 |
最近记录: |